Processing multiple simultaneous uploads with Cordova

This post is more than 2 years old.

I forget where, but a user on one of my posts recently asked about handling multiple uploads with Cordova, so I thought I'd whip up a quick demo. As always, the code below is all on GitHub (link will be at the bottom), so you can skip my post completely and just grab the bits if you want.

First off, the only reason this is even a little bit complex is because the upload method of the File Transfer plugin is asynchronous. Luckily there is an easy (heh, ok, kinda easy) way to handle multiple asynchronous responses - Promises. If you are using Ionic, then I'd strongly suggest using ngCordova. It includes a "Promise-fied" version of the File Transfer plugin already. But I didn't want to assume Angular so I decided to skip ngCordova and instead simply use the promise support from jQuery. (Reminder, I've got 2.5 hours of jQuery training, including promises, here: https://www.youtube.com/playlist?list=PL_z-rqJYNijrtVAc5qQbkzHnDELANGiOn)

For my demo, I simply used the Camera plugin to let you select multiple images from the device. Each image is added to the DOM. Here is that code:

var images = [];
var $imagesDiv;

document.addEventListener("deviceready", init, false);
function init() {
	
	$("#addPicture").on("touchend", selPic);
	$imagesDiv = $("#images");	
	$("#uploadPictures").on("touchend", uploadPics);
}

function selPic() {
	navigator.camera.getPicture(function(f) {
		var newHtml = "<img src='"+f+"'>";
		$imagesDiv.append(newHtml);
		images.push(f);
		if(images.length === 1) {
			$("#uploadPictures").removeAttr("disabled");
		}
	}, function(e) {
		alert("Error, check console.");
		console.dir(e);
	}, { 
		quality: 50,
		sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
		destinationType: Camera.DestinationType.FILE_URI
	});
	
}

I assume this stuff is rather simple, but if not, just let me know in the comments below. Here is a screen shot of the app in action.

iOS Simulator Screen Shot Aug 10, 2015, 5.23.33 PM

As you can guess, the upload button at the bottom there will begin the process. For my testing, I set up a ColdFusion script to simply save the uploads to a temporary directory. To add a bit of randonmness though, it will randomly reject images by outputting 0. On successful uploads, it will output 1.

Here is the remainder of the code:

function uploadPics() {
	console.log("Ok, going to upload "+images.length+" images.");
	var defs = [];

	images.forEach(function(i) {
		console.log('processing '+i);
		var def = $.Deferred();

		function win(r) {
			console.log("thing done");
			if($.trim(r.response) === "0") {
				console.log("this one failed");
				def.resolve(0);
			} else {
				console.log("this one passed");
				def.resolve(1);
			}
		}

		function fail(error) {
		    console.log("upload error source " + error.source);
		    console.log("upload error target " + error.target);
			def.resolve(0);
		}

		var uri = encodeURI("http://localhost/testingzone/test.cfm");

		var options = new FileUploadOptions();
		options.fileKey="file";
		options.fileName=i.substr(i.lastIndexOf('/')+1);
		options.mimeType="image/jpeg";

		var ft = new FileTransfer();
		ft.upload(i, uri, win, fail, options);
		defs.push(def.promise());
		
	});

	$.when.apply($, defs).then(function() {
		console.log("all things done");
		console.dir(arguments);
	});

}

So from top to bottom, what I'm doing is creating an array of promise objects. Or more specifically, the jQuery version of them. I then run an upload call for each image selected by the user. I check the result from the server and either resolve the promise with 0 or 1 based on what the server said.

Finally, I've got a call to $.when to handle waiting for all these asynch processes to finish. I don't actually show anything, I just console.dir, but you could imagine checking the results and doing - well - whatever makes sense.

I hope this is useful for folks, and as always, let me know if you have any questions. You can find the complete source here: https://github.com/cfjedimaster/Cordova-Examples/tree/master/multiupload

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Alin Pandichi posted on 8/12/2015 at 1:45 PM

"If you are using Ionic, then I’d strongly suggest using ngCordova."
ngCordova and its "Promise-fied" File Transfer plugin can be used even if you're not using Ionic. All it takes is AngularJS as the "engine" of your mobile app. I used it recently with PhoneGap / plain Cordova.

Comment 2 (In reply to #1) by Raymond Camden posted on 8/12/2015 at 4:34 PM

Yep, I was thinking that but typed too quickly. :)

Comment 3 by Ahmed Amine Gargoura posted on 4/18/2016 at 10:48 AM

Hi Raymond, Thank you for this post. It's really useful. Please I have a question: how can I integrate the progressEvent.
Actually I a kinda implement it but it only working when the upload start with the first image but the rest of images are not uploading. I should attached with every promise but i didn't found a solution. Please any tips?

Comment 4 (In reply to #3) by Raymond Camden posted on 4/18/2016 at 11:31 AM

There is no real way to do a 'meta' progressEvent for this. In theory, you could check the file sizes of the pics, and then in the progressEvent, figure out how much of one picture you've done, which in theory lets you know the percent total over all. Doable - just feels like a lot of work. I'd maybe just report as each image completes.

Comment 5 (In reply to #4) by Ahmed Amine Gargoura posted on 4/18/2016 at 3:07 PM

Thank you for the reply. Actually it works now for every Image. What I did, is that before uploading a pic I set a name for every image. Also, I make some editing because of the specification of my task. After That I used a switch case to make the progression for every image.

It's working as I want. For the record I am using angularJS

here my solution:

$scope.uploadPics = function (sell_hash) {
console.log("Ok, going to upload " + $scope.images.length + " images.");
var defs = [];
var sell_hash = sell_hash;
console.log(sell_hash);
$scope.upload_percentage_main = 0;
$scope.upload_percentage_main_show = false;

$scope.upload_percentage_detail_1 = 0;
$scope.upload_percentage_detail_1_show = false;

$scope.upload_percentage_detail_2 = 0;
$scope.upload_percentage_detail_2_show = false;

$scope.upload_percentage_detail_3 = 0;
$scope.upload_percentage_detail_3_show = false;

$scope.upload_percentage_detail_4 = 0;
$scope.upload_percentage_detail_4_show = false;

$scope.images.forEach(function (fileURI, count) {
console.log('processing ' + fileURI);
console.log(count);
var def = $.Deferred();

function win(r) {
console.log("thing done");
if ($.trim(r.response) === "0") {
console.log("this one failed");
def.resolve(0);
} else {
console.log("this one passed");
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
def.resolve(1);
}

}

function fail(error) {
console.log("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
def.resolve(0);
}

var uri = encodeURI("http://www.xxxxx.info/hhhh/...");
// var filename = fileURI.substr(i.lastIndexOf('/') + 1);
if (count === 0) {
var filename = 'main.jpg';
var directory_path = '/html/beta4/www/data/sell/' + sell_hash + '/main';
} else {
//var filename = fileURI.substr(fileURI.lastIndexOf('/') + 1);
var filename = 'detail_' + count + '.jpg';
var directory_path = '/html/beta4/www/data/sell/' + sell_hash;
}
var imageName = filename;

console.log(directory_path);
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = filename;
options.mimeType = "image/jpeg";
options.params = {'directory': directory_path, 'fileName': filename};

var ft = new FileTransfer();

ft.upload(fileURI, uri, win, fail, options);
defs.push(def.promise());
ft.onprogress = function (progressEvent) {
if (progressEvent.lengthComputable) {
console.log(progressEvent.loaded);
console.log(progressEvent.total);

switch (imageName) {
case 'main.jpg':
$scope.upload_percentage_main_show = true;
$scope.upload_percentage_main = Math.floor(progressEvent.loaded / progressEvent.total * 100);
$scope.$apply();
console.log($scope.upload_percentage_main);
console.log("here file name main");
break;

case 'detail_1.jpg':
$scope.upload_percentage_detail_1_show = true;
$scope.upload_percentage_detail_1 = Math.floor(progressEvent.loaded / progressEvent.total * 100);
$scope.$apply();
console.log($scope.upload_percentage_detail_1);
console.log("here file name detail_1");
break;

case 'detail_2.jpg':
$scope.upload_percentage_detail_2_show = true;
$scope.upload_percentage_detail_2 = Math.floor(progressEvent.loaded / progressEvent.total * 100);
$scope.$apply();
console.log($scope.upload_percentage_detail_2);
console.log("here file name detail_2");
break;

case 'detail_3.jpg':
$scope.upload_percentage_detail_3_show = true;
$scope.upload_percentage_detail_3 = Math.floor(progressEvent.loaded / progressEvent.total * 100);
$scope.$apply();
console.log($scope.upload_percentage_detail_3);
console.log("here file name detail_3");
break;

case 'detail_4.jpg':
$scope.upload_percentage_detail_4_show = true;
$scope.upload_percentage_detail_4 = Math.floor(progressEvent.loaded / progressEvent.total * 100);
$scope.$apply();
console.log($scope.upload_percentage_detail_4);
console.log("here file name detail_4");
break;

default:
alert('Perdu !');
}

}
};

});

$.when.apply($, defs).then(function () {
console.log("all things done");
// Cleans up the image files that were taken by the camera, that were stored in a temporary storage location.
navigator.camera.cleanup();
$scope.loading = false;
$scope.$apply();
// We should run the expression "$location.path("/sells");" as function in the $apply() method, to take effect
$rootScope.$apply(function () {
$location.path("/sells");
});

console.dir(arguments);

});

};

Comment 6 by Bahrul Ulum posted on 4/20/2016 at 5:06 PM

Hi Raymond, I want to ask, I followed your post, but when I choose more than 1 image, it only upload the latest one, even when I check the processed file on console log, it processed each image.
Can you help me?

Comment 7 (In reply to #6) by Raymond Camden posted on 4/20/2016 at 9:09 PM

I'd check on the server to ensure it isn't an issue there. That's all I can think of right now.

Comment 8 by Akash Pal posted on 5/5/2016 at 7:16 AM

I have a need to upload multiple images in one request using Cordova.
However the solution on the page sends the images in separate requests.

Is there a way to achieve multiple files upload in single request?
How can the file transfer plugin be modified to upload multiple files.

Comment 9 (In reply to #8) by Raymond Camden posted on 5/5/2016 at 1:42 PM

I can't speak to modifying the File Transfer plugin. You would need to look at the source code. As for how I'd do it in JavaScript, the XHR2 specification allows for file uploads in a POST operation. You could use that to send multiple items in one POST.

Comment 10 (In reply to #9) by Akash Pal posted on 5/5/2016 at 5:16 PM

Could you provide an implementation of uploading multiple images using XHR2 and mutli image picker plugin?

without using <input type="file" multiple="">

I have tried modifying the File Transfer Plugin but it hasnt worked.

Comment 11 (In reply to #10) by Raymond Camden posted on 5/5/2016 at 5:54 PM

Yes - I will have a demo on this blog in about two hours. I won't post back here, so just check the blog in - well - 2 to 3 hours.

Comment 12 (In reply to #11) by Akash Pal posted on 5/5/2016 at 6:08 PM

Kindly implement using cordova.
Do provide the link?

Comment 13 (In reply to #12) by Raymond Camden posted on 5/5/2016 at 6:12 PM

It won't be in Cordova, but will be in code you can easily use in Cordova. I don't have a link as it isn't published yet. Just come back to the blog and look for the latest entry. :)

Comment 14 (In reply to #13) by Akash Pal posted on 5/5/2016 at 6:15 PM

Okay I can implement it in cordova if the implementation is done only with image URI. As this plugin https://github.com/wymsee/c...
returns image URI of the selected images.

My objective is to select multiple images from gallery and upload in one request.

Comment 15 (In reply to #14) by Raymond Camden posted on 5/5/2016 at 6:17 PM

Well I'd suggest reading my blog post. It is a generic solution that you should be able to apply. For a *specific* solution to fit your needs, if you want me to write that it would have to be a paid engagement.

Comment 16 (In reply to #15) by Akash Pal posted on 5/5/2016 at 6:22 PM

I have gone through your blog post however it uploads images in separate requests. I just require some guidance to achieve my objective. I would appreciate any help from your side. Thank you.

Comment 17 (In reply to #16) by Raymond Camden posted on 5/5/2016 at 6:25 PM

I don't think you understand me. The blog post isn't done yet. I'm writing a *new* blog post. Like right now. Check the blog (go to www.raymondcamden.com) in about an hour and see the *new* post.

Comment 18 (In reply to #17) by Akash Pal posted on 5/5/2016 at 6:28 PM

I do get you. I do appreciate for taking out your time for this. Will definitely check out your blog within an hour.

Comment 19 (In reply to #8) by laersheng posted on 5/25/2016 at 4:46 PM

I have this need too,have you resolved it?

Comment 20 (In reply to #19) by Raymond Camden posted on 5/25/2016 at 4:55 PM

I did - see my later posts. :) (Right hand side of blog has latest posts.)

Comment 21 by rod Dickinson posted on 6/21/2016 at 5:32 PM

Dear Raymond, thank you for this and your other cordova tutorials - and the github repository of them all. I have a quick question about implementing this file transfer example. I've used a php script (tested in a browser) and it keeps returning Undefined index: fileToUpload. It seems to not recognise the incoming file.
I'm pretty sure this is an issue with the sever / php not your cordova example and I wondered if you had come across anything like it? (I realise you are using cold fusion).
Thanks!

Comment 22 (In reply to #21) by Raymond Camden posted on 6/21/2016 at 5:38 PM

Does PHP have a way to dump the entire scope of form fields? If so, I'd use that to see what is being sent to it.

Comment 23 (In reply to #22) by rod Dickinson posted on 6/21/2016 at 11:16 PM

Hi Raymond, thanks it does (var_dump($_POST)) and that helped a lot.

I now have this working in iOS8 and Android lollipop (on actual devices and a remote server with a php script).

I added some params to your uploadPics() which get passed to the php script.

uploadPics() snippet:

var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=i.substr(i.lastIndexOf('/')+1);
options.mimeType="image/jpeg";

//added
var params = new Object();
params.directory = "uploads"; //must correspond with $_POST['directory']
params.fileName = i.substr(i.lastIndexOf('/')+1); //must correspond with $_POST['fileName']

options.params = params;
//end added

var ft = new FileTransfer();

Then the php script (very basic and for testing only as contains no security checks):

This post
http://www.gajotres.net/usi...
contained all of the above.

Hope this is useful to someone.

Comment 24 (In reply to #23) by rod Dickinson posted on 6/21/2016 at 11:19 PM

The php script in its entirety

$location = $_POST['directory'];
$uploadfile = $_POST['fileName'];
$uploadfilename = $_FILES['file']['tmp_name'];

if(move_uploaded_file($uploadfilename, $location.'/'.$uploadfile)){
echo 'File successfully uploaded!';
} else {
echo 'Upload error!';
}

Comment 25 by Darwin Naranjo posted on 7/4/2016 at 1:57 AM

Your examples is great! any other example with progress bar?

Comment 26 (In reply to #25) by Raymond Camden posted on 7/4/2016 at 1:31 PM

Nope, sorry. Technically possible of course.

Comment 27 by Sundaravel M posted on 8/2/2016 at 8:52 AM

Thanks for tutorial, I found some simple & useful article for uploading images to php server using phonegap file transfer plugin http://phonegappro.com/tuto...

Comment 28 by Sarah posted on 9/10/2016 at 4:26 PM

Hi thank you for this.. is there any way to restrict the size of the file uploaded?

Comment 29 (In reply to #28) by Raymond Camden posted on 9/10/2016 at 4:33 PM

Yes. You would need to use the File plugin to get the size. You could then add restrictions on a per file basis (no image over X) and/or a total.

Comment 30 (In reply to #29) by Sarah posted on 9/10/2016 at 4:54 PM

great thanks. and i was also wondering do you know the best way to allow the user to crop an image after they select it? in my app i want a user to select a photo for their profile pic and i want the profile pic to be of dimensions approx 200X200px before it is uploaded. thanks

Comment 31 (In reply to #0) by Raymond Camden posted on 9/11/2016 at 3:53 PM

The Camera plugin allows for simple editing, but I'm not sure what that will allow for *existing* pictures.

Comment 32 (In reply to #31) by Sarah posted on 9/11/2016 at 4:39 PM

great thanks for the information :)

Comment 33 by Sarah posted on 10/16/2016 at 9:19 PM

Hi Raymond. I was wondering can you help (again lol).. I had the file transfer code in your tutorial working successfully in a phonegap build with adobe phonegap. using the following in my config file: <gap:plugin name="org.apache.cordova.file-transfer" spec="0.5.0" source="pgb"/> but now in my phonegap account they are telling me the following "This app uses plugins from the PhoneGap Build repository. These plugins won't be accessible after Nov 15th, 2016" so ive researched this a bit and ive found out that you should change to the npm version of the plugin. so i tried this in my config: <plugin name="cordova-plugin-file-transfer" source="npm" version="1.3.0"/> however its not working.... any ideas? thanks

Comment 34 (In reply to #33) by Raymond Camden posted on 10/16/2016 at 9:24 PM

How is it not working?

Comment 35 (In reply to #34) by Sarah posted on 10/16/2016 at 9:30 PM

well it doesnt seem to be executing the code anymore as the file transfers are not coming back as passed or failed...

Comment 36 (In reply to #35) by Raymond Camden posted on 10/16/2016 at 9:34 PM

Do you see anything when you do a remote debug?

Comment 37 by Tony Davidson posted on 11/25/2016 at 6:10 PM

Hi Raymond,

Firstly, thank you for putting up the code, it works really well at uploading multiple images. However, I am having a few problems getting the following part of the code to fire :

$.when.apply($, defs).then(function() { });

I can upload many images successfully and get the responses back to my terminal telling me it has completed. It looks like the Deferred objects aren't being resolved.

It would be great if you could look over my code and perhaps give me a hint of where I have gone wrong. I think my understanding of Deferred and Promises is lacking. I don't understand the purpose of the arguments being passed in the def.resolve(1) or def.resolve(0) calls.

My function takes objects from a array of objects holding references to .png files which were captured using an html canvas. The $.when.apply($, defs).then(function() { }); does fire if there are no objects in the array or an error is returned.

function syncSignatures() {
var defs = [];
var i;
$(".loader").show();
for(i = 0; i < signatureCache.signatures.length; i++){
var def = $.Deferred();
var image;

function win(r) {
console.log("thing done : ", r);
if($.trim(r.response) === "0") {
console.log("this one failed");
def.resolve(0);
} else {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
var file = r.response;
file = file.replace(" uploaded successfully", "");
for(s = 0; s < signatureCache.signatures.length; s++){
var sig = signatureCache.signatures[s];
if(sig.fileName == file){
signatureCache.signatures.splice(s, 1);
break;
}
}
def.resolve(1);
}
}
function fail(error) {
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
console.log("upload http status " + error.http_status);
console.log("upload error body " + error.body);
def.resolve(0);
}

image = signatureCache.signatures[i];
var options = new FileUploadOptions();
console.log(image.signature);
options.fileKey = "file";
options.fileName = image.fileName;
options.mimeType = "image/jpeg";
options.chunkedMode = true;

var params = {};
params.jobId = image.jobid;
params.deviceUUID = image.deviceUUID;
params.name = image.name;
params.timestamp = image.timestamp;

options.params = params;

var ft = new FileTransfer();
ft.upload(image.signature, encodeURI(baseUrl+'syncImages'), win, fail, options);
defs.push(def.promise());
}
$.when.apply($, defs).then(function() {
console.log("all signatures uploaded");
console.dir(arguments);
$(".loader").hide();
});
}

Once again, thank you for the original code, as with other topics you discuss on your blog it is incredibly helpful and clearly written and so helpful to someone like me embarking on a career as a software developer.

Comment 38 (In reply to #37) by Raymond Camden posted on 11/26/2016 at 3:41 PM

Well first off - does the *original* code work for you? As for what resolve(1) and resolve(0) were doing: They are basically saying, "This particular Promise is done and either had a good or bad result." I could have used reject() as well to return an error, but decided on using a status result (1 or 0) instead.

Also - please post your code someplace else, like Pastebin, as it is too hard to read here.

Also - be sure to test with remote debugging and report on what you see in the console.

Comment 39 by Sarah posted on 2/8/2017 at 10:41 PM

Hi Raymond. I was wondering can you help again? :) I've been using the file transfer plugin in my project and works grand. thanks :) As I am packaging up the app with phonegap build, I have been sending the images to a php page on a remote server and all working grand. I used the following header in the php page header("Access-Control-Allow-Origin: *"); Now I have decided to use ssl on my server so now I am trying to send the images to a uri with https:// e.g var uri = encodeURI(https://wwwexample.com/uplo..."); However the images are failing and I am getting the following error: "http_status":406, "body":"<head>Not Acceptable!</head><body>An appropriate representation of the requested resource could not be found on this server. This error was generated by Mod_Security</body>".. I have looked up error 406 and it seems to be to do with the headers. I was just wondering would you know how to fix it? thanks

Comment 40 (In reply to #39) by Raymond Camden posted on 2/9/2017 at 8:14 PM

Hmm - maybe try trustAllHosts option defined here: https://cordova.apache.org/...

Comment 41 (In reply to #40) by Sarah posted on 2/23/2017 at 6:35 PM

Ok thank you :)

Comment 42 by Mani Raj posted on 3/17/2017 at 7:00 AM

In my case duplicate images are uploaded even i choose different images in android.but its working in simulator.Any issue related to this?

Comment 43 (In reply to #42) by Raymond Camden posted on 3/17/2017 at 2:50 PM

I'd need to know more, debug, etc.

Comment 44 (In reply to #43) by Mani Raj posted on 3/20/2017 at 6:10 AM

I removed correctOrientation: true issue was fixed

Comment 45 by Derp posted on 3/27/2017 at 7:58 AM

How do i go on about to upload video type files too?

Comment 46 (In reply to #45) by Raymond Camden posted on 3/27/2017 at 2:07 PM

What did you try? This post demonstrates how to do it with images, but the source doesn't really matter. You should be able to apply this to any file.

Comment 47 (In reply to #46) by Derp posted on 3/27/2017 at 3:39 PM

I tried it with the original source code and I've added the cordova plugins (file-transfer & camera) and using my own php file but sadly I'm not able to add any other source other than image (jpeg).

I'm new to ionic so my knowledge isn't that vast. I switched out the mimetype to video/mp4 and it doesn't work on either android or ios via ionic view. Could you point me in the right direction as to what I'm doing wrong.

Thanks a bunch and I know you get this kind of questions alot.

Comment 48 (In reply to #47) by Raymond Camden posted on 3/27/2017 at 5:23 PM

Not sure what I can tell you here - the changes you made were correct, but you also have to change *where* the files are sourced from. You need to figure out what directory holds your video files so you can properly address them with the FileTransfer plugin.

Comment 49 by Alex posted on 5/3/2017 at 10:37 AM

I'm trying to upload 100 plus photos.. some photos were not uploaded about half of the total number of photos are missing.. is there any other method to do multiple uploads?

Comment 50 (In reply to #49) by Raymond Camden posted on 5/3/2017 at 12:59 PM

You could zip the files first so you just have one file to upload. You could also try to re-upload the ones that fail.

Comment 51 (In reply to #50) by Alex posted on 5/4/2017 at 6:43 AM

Thanks for the reply Raymond Camden.. how do I do re-upload the ones that fail? can you give me some idea? thanks!

Comment 52 (In reply to #51) by Raymond Camden posted on 5/4/2017 at 11:36 AM

You would use an error handler, note the files that failed, and try again. Perhaps you can keep calling an 'upload' routine until the list of files is 0, or use a sanity check of some sort that stops this after 5 tries.

Comment 53 (In reply to #52) by Alex posted on 9/27/2017 at 1:31 PM

Thanks! how about zipping the taken photos? do you have any tutorials for that?

Comment 54 (In reply to #53) by Raymond Camden posted on 9/27/2017 at 3:46 PM

There are a few libraries for client-side zipping. I haven't used them in a while, but Google for JavaScript zip library and you will find some options. In general, I don't trust binary heavy stuff in JS, but it's an option.

Comment 55 (In reply to #54) by Alex posted on 9/28/2017 at 10:02 AM

Thank you for your reply, but, this is doable, right? uploading hundreds of photos to server using web APIs?

Thanks!

Comment 56 (In reply to #55) by Raymond Camden posted on 9/28/2017 at 1:01 PM

... well... maybe. "hundreds" is a lot, and depending on your network connection it may or may not be doable. You *can* look at the connection speed and you can do things like, I have A,B,C to upload, as I process, mark them off the list so that if things go wrong, I can resume later.

I'd say doable - just expect your complexity to go up.

Comment 57 by Saj posted on 11/4/2017 at 9:40 AM

Similarly, how can i browse and read as text then upload a JSON/XML file in cordova app? Could you please post a tutorial? It will be very helpful. Thanks

Comment 58 (In reply to #57) by Raymond Camden posted on 11/4/2017 at 8:34 PM

The filesystem plugin lets you do file system operations. So it can list, read directories and files. To make a 'browser' you would use the plugin and render stuff so the user can navigate.

As for uploading, that's the filetransfer plugin which is officially (afaik) deprecated now that there is support for it in native browser JavaScript (but you can still use the plugin).