Reputation: 19571
The below is supposed:
img
tagssrc
urlbase64
encoded string using a HTML 5
canvas
My problem:
canvas
before I can convert it to base64
img.src = element.src;
each time through resolves the promise, it doesn't wait for the images to load and call return base64Img;
so I end up with an empty array when $.when.apply($, promises).then(function(){});
is called.How can I change this promise so that it does not resolve until all the images have been loaded and converted?
function accountCreation(){
$('#container').hide(); // hide the display while we save the info as it will take a few seconds, you should do a loading bar or something here instead
var user = Parse.User.current(); // get the currently logged in user object
// loop through each image element
var promises = $('.images').map(function(index, element) {
var src = $(element).attr('src');
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var img = new Image;
img.crossOrigin = 'Anonymous';
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img,0,0);
var base64Img = canvas.toDataURL('image/png');
// Clean up
canvas = null;
return base64Img;
};
img.src = element.src;
});
$.when.apply($, promises).then(function() {
// arguments[0][0] is first result
// arguments[1][0] is second result and so on
for (var i = 0; i < arguments.length; i++) {
var file = new Parse.File("photo.jpg", { base64: arguments[i]}); // this part actually saves the image file to parse
user.set("image" + i, file); // set this image to the corosponding column on our object
}
// save the user object
user.save(null,{
success: function(user) {
$('#message').html('Profile Updated!');
$('#container').show(); // show the screen again, you should just remove your loading bar now if you used one
},
error: function(user, error) {
console.log('Failed to create new object, with error code: ' + error.message);
}
});
});
}
Upvotes: 0
Views: 2225
Reputation: 700622
Your array of promises just contains undefined values, as the callback function doesn't return anything. As there are no Deferred
objects in the array, the when
method doesn't have anything to wait for, so it runs the then
callback right away.
Create a Deferred
object to return, and resolve it when the image is loaded:
var promises = $('.images').map(function(index, element) {
// created a Deferred object to return
var deferred = $.Deferred();
var src = $(element).attr('src');
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var img = new Image;
img.crossOrigin = 'Anonymous';
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img,0,0);
var base64Img = canvas.toDataURL('image/png');
// Clean up
canvas = null;
// Resolve the Deferred object when image is ready
deferred.resolve(base64Img);
};
img.src = element.src;
// return the Deferred object so that it ends up in the array
return deferred;
});
Upvotes: 1