Reputation: 387
I want to upload a cropped image with jquery ajax. Therefore I create a blob out of the canvas element to append it to the form data. This works fine so far but I have some sync/async problems I guess. I searched the web for javascript callbacks but I'm not sure if this is the correct thing in general here. The problem is that
return formData;
will be executed before the blob is added to the form data. I think there is an easy solution to solve my problem but I can't get it done, maybe you can help me.
$.ajax({
url: this.$upload.data('url'),
method: 'POST',
contentType: false,
processData: false,
cache: false,
data: (function(_this) {
var formData = new FormData();
_this.getCroppedImage().toBlob(
function(blob) {
formData.append('file', blob, _this.file.name);
},
_this.file.type
);
$.each(_this.$element.data(), function(key, value) {
formData.append(key, value);
});
return formData;
})(this)
});
Maybe it's important to know: I also use https://github.com/blueimp/JavaScript-Canvas-to-Blob to have the toBlob method available to all browsers.
Upvotes: 2
Views: 4400
Reputation: 2885
To accomplish this you're going to want to look into promise objects, a good library for this is q.js
Basically you create a function that will build your form data, and then you wait for the form data to be completed, when the promise resolves it will pass the form data into your ajax function via the "then" callback. Then your ajax call will be run
function ajaxFn(){
//result is your formData in this case
getFormData().then(function(result){
//this won't run until the promise resolves, aka formData is complete
$.ajax({
url: this.$upload.data('url'),
method: 'POST',
contentType: false,
processData: false,
cache: false,
data: result
});
});
}
function getFormData(){
var deferred = Q.defer();
var formData = new FormData();
$.each(_this.$element.data(), function(key, value) {
formData.append(key, value);
});
_this.getCroppedImage().toBlob(
function(blob) {
formData.append('file', blob, _this.file.name);
//this is what will get passed into your then function above
deferred.resolve(formData);
},
_this.file.type
);
return deferred.promise;
}
Upvotes: 1