AngularJS Array of Promises
You must push a promise, not a deferred, to the promises
array:
promises.push(deferred.promise);
It helps if you think about it like this:
- the promise is a read-only object you want to return to the consumers
- deferred is the modifier of that read-only promise and you want to keep it for yourself
![Daniel Bonnell](https://i.stack.imgur.com/IXenf.jpg?s=256&g=1)
Daniel Bonnell
Senior fullstack software engineer with executive management experience seeking a challenging but rewarding opportunity with a forward thinking team on an innovative product.
Updated on August 16, 2022Comments
-
Daniel Bonnell almost 2 years
Can anyone help me with some Angular promises? I have the following functions that should take in an array of file objects, iterate over them, and upload each one. During each iteration, a promise object is pushed to an array of
promises
. Within myupload
function I have acycle
function with a.then()
attached, which should not be called until all the promise objects have resolved. I think my code looks correct, but it's not working right. The images upload, butcycle(files).then()
is being called immediately, rather than once thepromises
array resolves.function upload(files) { var uploadCount = files.length; function cycle(files) { var promises = []; for (var i = 0; i < files.length; i++) { var deferred = $q.defer(); promises.push(deferred); var file = files[i]; Upload.upload({ url: '/photos.json', file: file }).success(function(){ $scope.progressCurrentCount += 1; deferred.resolve(); }); }; return $q.all(promises); }; cycle(files).then(function(result) { if(uploadCount > 1) { $scope.lastAction = 'uploaded ' + uploadCount + ' photos'; } else { $scope.lastAction = 'uploaded ' + uploadCount + ' photo'; } $scope.showSuccessModal = true; $scope.uploading = false; $scope.failedUploads = []; $scope.newPhotos = { token: $scope.token, files: undefined }; photoUploadBtn.removeClass('disabled'); }) };
Final working code*
Rather than setting
var deferred = $q.defer();
pushingdeferred.promise
into thepromises
array, and then resolvingdeferred
in my.success()
callback, which wasn't working, I just push myUpload.upload()
function without the.success()
callback intopromises
, and then pass that to$q.all()
, which does all the lifting.function upload(files) { var uploadCount = files.length; function cycle(files) { var promises = []; for (var i = 0; i < files.length; i++) { var file = files[i]; var promise = Upload.upload({ url: '/photos.json', file: file }); promises.push(promise); }; return $q.all(promises); }; cycle(files).then(function(result) { if(uploadCount > 1) { $scope.lastAction = 'uploaded ' + uploadCount + ' photos'; } else { $scope.lastAction = 'uploaded ' + uploadCount + ' photo'; }; $scope.showSuccessModal = true; $scope.uploading = false; $scope.failedUploads = []; $scope.newPhotos = { token: $scope.token, files: undefined }; photoUploadBtn.removeClass('disabled'); getPhotos(q); }) };
-
Daniel Bonnell almost 9 yearsThanks, that was most of the solution I needed! I also came upon this article, which made me realize that I should approach things slightly differently. I'll put my final code in my post above.