简体   繁体   中英

How to do http post for image in nativescript-angular

so I'm trying to upload an image from the user's gallery to my API. Currently, I can select the image from the gallery but it's not letting me pass that selected image into another function to send it to the API. There is no problem with the API, that has been tested. I am using the "nativescript-imagepicker" plugin

This is the code:

  getImage() {
        let context = imagepicker.create({
            mode: "single" // use "multiple" for multiple selection
        });

    context
        .authorize()
        .then(function () {
            return context.present();
        })
        .then(function (selection) {
                selection.forEach(function (selected) {
                console.log(selected)
                this.uploadImage(selected)
            });
        })
        .catch(function (e) {
            console.log('error')
            // process error
        });
}

uploadImage(imageAsset) {

    console.log('uploading image')

    let token = JSON.parse(appSettings.getString('token'));
    let options = new HttpHeaders({
        "Content-Type": "application/x-www-form-urlencoded",
        // "Content-Type": "application/octet-stream",
        "Authorization": "Bearer " + token
    });
    let userId = appSettings.getString('currentUserId')
    let url = 'http://localhost:5000/api/users/' + userId + '/photos'
    console.log(url)
    this.http.post(url, imageAsset, { headers: options }).subscribe(res => {
        console.log(res)
        console.log('Success')
    }, error => {
        console.log('Failed');
    });
}

It runs the getImage function and takes me to the gallery, then once the image is selected, it runs the console.log function (which works so the image is being received I believe & it logs the route to the image). This is the output for the console.log

{
JS:   "_observers": {},
JS:   "_options": {
JS:     "keepAspectRatio": true,
JS:     "autoScaleFactor": true
JS:   },
JS:   "_android": "/storage/emulated/0/DCIM/Camera/IMG_20200211_200350.jpg"
JS: }

It doesn't, however, run the 'this.uploadImage' function with the image, so instead it skips over this and goes to the '.catch' block and logs 'error'. It also logs this in the console

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'uploadImage' of undefined
JS: TypeError: Cannot read property 'uploadImage' of undefined
JS:     at file:///src\app\_mocks\test\test.component.ts:38:25
JS:     at Array.forEach (<anonymous>)
JS:     at file:///src\app\_mocks\test\test.component.ts:36:30
JS:     at ZoneDelegate.push.../node_modules/nativescript-angular/zone-js/dist/zone-nativescript.js.ZoneDelegate.invoke (file:///node_modules\nativescript-angular\zone-js\dist\zone-nativescript.js:388:0)
JS:     at Object.onInvoke (file:///node_modules\@angular\core\fesm5\core.js:26256:0)
JS:     at ZoneDelegate.push.../node_modules/nativescript-angular/zone-js/dist/zone-nativescript.js.ZoneDelegate.invoke (file:///node_modules\nativescript-angular\zone-js\dist\zone-nativescript.js:387:0)
JS:     at Zone.push.../node_modules/nativescript-angular/zone-js/dist/zone-nativescript.js.Zone.run (file:///data/d...

Imports

import * as fs from "tns-core-modules/file-system";
import * as camera from "nativescript-camera";

Functions

    // This method allows the user to take a picture, save to the gallery, display it on the screen, convert it to base64 and then send it to the API   
  1. Take picture, save to gallery, save as a base64 string, display on the screen

    takePicture() { const options = { width: 300, height: 300, keepAspectRatio: false, saveToGallery: true }; camera.takePicture(options). then((imageAsset) => { console.log("Size: " + imageAsset.options.width + "x" + imageAsset.options.height); console.log("keepAspectRatio: " + imageAsset.options.keepAspectRatio); console.log("Photo saved in Photos/Gallery for Android or in Camera Roll for iOS"); const imgPhoto = new ImageSource(); const that = this; imgPhoto.fromAsset(imageAsset).then((imgSrc) => { if (imgSrc) { // This is the base64 string, I saved it to a global variable to be used later that.bstring = imgSrc.toBase64String("jpg"); console.log(that.bstring); // This bit saves it as an 'Image' to the app const mil = new Date().getTime(); const folder = fs.knownFolders.documents(); const path = fs.path.join(folder.path, `SaveImage${mil}`); const saved = imgPhoto.saveToFile(path, "png"); // This saves the image to the global variable which will be used to display it on the screen that.saveImage = path; that.picHeight = imgSrc.height; } else { alert("Image source is bad."); } }); }).catch((err) => { console.log("Error -> " + err.message); }); }
  2. Send it to the API

     // This is just a generic API call that uses the base64 string as the image // you can choose whether to call the function and pass the image into it, or just use the one saved in the global variable uploadImage(image = null) { const imageString; if (image) { let imageString = image } else { imageString = this.b64image } // This is where you create the object to be sent up to the API, in this example I'm sending up a description aswell, so I've added the property here const data = { B64String: imageString, Description: this.imageDescription }; // This is where i create my headers, in this case I'm using authorization const headers = new HttpHeaders({ Authorization: "Bearer " + appSettings.getString("tok") }); // This is my API call this.http.post(this.baseUrl + "users/" + this.userId + "/photos", data, { headers}) .subscribe((res) => { console.log(res) }, (error) => { console.log(error) } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM