Nativescript: Image upload using Nativescript.

Created on 23 Dec 2016  路  13Comments  路  Source: NativeScript/NativeScript

Hello everyone,

I need some help on image upload using nativescript.

I have tried every example available for nativescript. i have used nativescript-background-http,nativescript-imagepicker,image-upload,camera,etc...

when i tried these examples,all are showing image uploaded but actually it is not uploaded in server.i'm using node js(strongloop containers) for storing the images.

question

All 13 comments

Hi @narender56

From your post, I guess you have already tested this sample app. If not then please try to upload a photo to your server via this POC application.

However, to investigate your issue we will need more information -e.g. is your application or server throwing an error? On what platform you ar working (iOS or Android) and what you have tried so far. The best approach is to share a sample code of what you have achieved up to this moment and what exactly you are experiencing as behaviour in your application.

@narender56 - I assume the issue your are facing is the multipart-form-data image upload is what most servers are expecting is why your tries have all failed as none of those support it. I do have a fully working pull request for the nativescript-background-uploader plugin that adds MFD to it for both iOS and Android. One of my clients has been using it for a while; I just haven't had the time to actually upload a pull request to the main repo. I'll try and get this done next week. If you don't see anything from me by Wednesday, please feel free to ping me to remind me. :grinning:

Hi @NickIliev ,

Thanks for answering,please have a look at this snippet of code.i'm storing image in local mongo DB , when i upload from rest-client it saving fine but from nativescript is not happening,in console logs are showing uploaded.

exports.takephoto = function(uri, fileUri) 
{

    cameraModule.takePicture({ width: 800, height: 800, keepAspectRatio: true }).then(function(picture) {
        var savepath = fs.knownFolders.documents().path;
        var filename = 'img_by_sj_' + new Date().getTime() + '.jpg';
        var filepath = fs.path.join(savepath, filename);
        var picsaved = picture.saveToFile(filepath, enumsModule.ImageFormat.jpeg);
        if (picsaved) {
            console.log("Saving");
            var session = bghttp.session("image-upload");
            var request = {
                url: "http://localhost:7777/api/containers/SocialSiteProfilePicDB/upload",
                method: "POST",
                headers: {
                    "Content-Type": "application/octet-stream",
                    "File-Name": filename
                },
                description: "{ 'uploading': '" + filename + "' }"
            };

            var task = session.uploadFile("file://" + fileUri, request);

            task.on("progress", logEvent);
            task.on("error", logEvent);
            task.on("complete", logEvent);

            function logEvent(e) {
                console.log(e.eventName);
            }
        } else {
            console.log("Failed To Save");
        }
    });
}

@narender56 looking at your example I saw that you are creating your fileUri like _"file://" + fileUri_,.
Not sure what you are passing for fileUri but in any case, you should be able to pass your _filepath_ from

var filepath = fs.path.join(savepath, filename);

and that would be the valid fileUri you are looking for (not need for file prefix as path.join will return your normalised path).

For reference look here

@Hi @NathanaelA ,

Still waiting for your help on image upload. :grinning:

@narender56 I've noticed that you are testing with _localhost_. Now depending on whether you are testing on real device or emulator it might not work as expected. For iOS it is ok but for Android localhost (or 127.0.0.1) won't work through emulators where the loopback addresses are something like 10.0.2.2 (for AVD created emulators.. for Genymotion the address might be different)

Hi @NickIliev , Actually i'm using rest api url like 139.120.32.12:7779/api, for this also not working.

@narender56

After some close inspection of your snippet I noticed that in the following line
var task = session.uploadFile("file://" + fileUri, request); you are passing _fileUri_
(which comes from the takePhoto arguments) however, the path to your saved file is defined in

var filepath = fs.path.join(savepath, filename);

Another thing I noticed is that you are probably using the old nativescript-camera module as the latest version is no longer returning imageSource in the promise but imageAsset . That is made to implement some memory optimisation techniques when working with images in NativeScript.
So to take a photo, save to a file and then upload this file I 've refactored your snippet to look like this (also used http://posttestserver.com/ to test if the image is uploading).

     camera.takePicture({ width: 800, height: 800, keepAspectRatio: true }).then(imageAsset => {

        var savepath = fs.knownFolders.documents().path;
        var filename = 'img_by_sj_' + new Date().getTime() + '.jpg';
        var filepath = fs.path.join(savepath, filename);

        var imageSource:imageSourceModule.ImageSource;

        // as the latest nativescript-camera is returing imageAsset we have to take one additioanl step here
        imageSourceModule.fromAsset(imageAsset).then(res => {
            imageSource = res;        
            var picsaved = imageSource.saveToFile(filepath, "jpg");

            console.log("filepath: " + filepath);

            if (picsaved) {
                console.log("Saved!");
                var session = bghttp.session("image-upload");
                var request = {
                    url: "http://posttestserver.com/post.php?dir=nativescript",
                    method: "POST",
                    headers: {
                        "Content-Type": "application/octet-stream",
                        "File-Name": filename
                    },
                    description: "{ 'uploading': '" + filename + "' }"
                };

                // pass filepath here instead of fileUri and no need for file:// in this case
                var task = session.uploadFile(filepath, request);

                task.on("progress", logEvent);
                task.on("error", logEvent);
                task.on("complete", logEvent);
            } else {
                console.log("Failed To Save");
            }
        })
    });

The example above will upload the file in _http://posttestserver.com/data/YEAR/MONTH/DAY/nativescript_
and after test, the image was successfully uploaded here

@narender56 - I've uploaded my pull request to the nativescript-background-http plugin. If they accept it, I would assume the next version of the plugin would have the ability which will solve a lot of peoples upload issues. If you know git well enough you can clone my repo and use the multipart branch and install that as the plugin and then have it today.

Hey @NathanaelA , good to see you again, thanks for your reply . Generally how much time it takes to approval of this plugin?

I have no idea; I don't work for Telerik; I'm just a independent contractor/freelancer. Some times they approve things quickly and other times it takes a while. But even after they do the pull request; they might not release it as a updated plugin via npm until a later point...

@NickIliev how is the file requested on the server? An example would be great.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rLoka picture rLoka  路  3Comments

OscarLopezArnaiz picture OscarLopezArnaiz  路  3Comments

minjunlan picture minjunlan  路  3Comments

dhanalakshmitawwa picture dhanalakshmitawwa  路  3Comments

hshristov picture hshristov  路  3Comments