I am using the following snippet for my conversion operation (images from cordova image picker to base64 and store them in an array) but due to the async behavior, it is assigning same string as of the first image to all images. I tried while loop but then, the app crashed. Any suggestion how can I solve this problem.
Edit: results[ 0 ] is defined but all other results[ i ] are 'undefined', hence image source remains same for all iteration
window.imagePicker.getPictures(
function(results) {
for (var i = 0; i < results.length; i++) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.src = results[i];
img.onload = function(){
var canvas = <HTMLCanvasElement>document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage( img, 0, 0);
var dataURL = canvas.toDataURL('image/jpeg').slice(23);
Attachments.push(dataURL); // array for storing base64 equivalent of all images
canvas = null;
};
}
img.src = results[ i ] starts reading the file at results[ i ] async, so when loop continues for i=1, results[ 1 ] is undefined because the file system is still reading for results[0]. Hence all iteration returns dataURL of the first image.
To avoid it use callbacks which solve this problem with the concept of closures.
window.imagePicker.getPictures(
function(results) {
console.log(results);
for (var i = 0; i < results.length; i++) {
parent.tobase64(results[i],function(dataURL){
parent.email_data.Attachments.push(dataURL);
});
}
}, function (error) {
console.log('Error: ' + error);
}
}
tobase64(file,callback){
var parent=this;
var img = new Image();
img.crossOrigin = 'Anonymous';
img.src = file;
img.onload = function(){
var canvas = <HTMLCanvasElement>document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage( img, 0, 0);
var dataURL = canvas.toDataURL('image/jpeg').slice(23);
canvas = null;
callback.call(this,dataURL);
}
}