0

I'm trying to understand promises and $q in AngularJS. I'd like to chain 2 functions, and execute them in order. The first is a file upload, and can take a while, so I need to wait for it to be executed before creating a DB record for it. I was originally using angular 1.3, hence the .success and .error methods.

Here's the code:

    //image upload function 

    $scope.imageUpload = function(){
        return $q(function (resolve, reject) {
              var fd = new FormData();
              fd.append("file", $scope.imageFile);
              var data = fd;
              var url = 'http://myApiUrl';
              var postObject = {
                  method: 'POST',
                  url: url,
                  data: data
              }
              $http(postObject)
                 .success(function(response) {
                     return response; 
              }).error(function(response) {
                     return response; 
              });
          })
      }

    // create a DB record 
    $scope.recordCreate = function(previousResponse){
          return $q(function (resolve, reject) {

               // does stuff with previousResponse, and creates a db record

            })
        };

    // do functions in order 

    $scope.imageUpload().then(
            $scope.recordCreate(response)
          );

Not only am I getting the error

ReferenceError: response is not defined

(in relation to that last line, $scope.recordCreate(response)), but also the second function is executing BEFORE the first!

I have tried to follow the docs here https://docs.angularjs.org/api/ng/service/$q but in my example I can't get my first function to return a response to the 2nd. Does anyone know why?

Leon
  • 1,851
  • 3
  • 21
  • 44
  • 1
    The `.success` and `.error` methods **ignore return values**. See [Why are angular $http success/error methods deprecated? Removed from v1.6?](http://stackoverflow.com/a/35331339/5535245). – georgeawg Mar 24 '17 at 18:38
  • Possible duplicate of [Why are angular $http success/error methods deprecated? Removed from v1.6?](http://stackoverflow.com/questions/35329384/why-are-angular-http-success-error-methods-deprecated-removed-from-v1-6) – georgeawg Mar 24 '17 at 18:38
  • 1
    Also there is no need to manufacture a promise with `$q(resolve, reject)` as the $http service already returns a promise. See [Is this a “Deferred Antipattern”?](http://stackoverflow.com/questions/30750207/is-this-a-deferred-antipattern). – georgeawg Mar 24 '17 at 18:43
  • BTW the file upload code doesn't work. You might want to fix that before trying to chain from it. See [How to POST a File Using the $http Service](http://stackoverflow.com/a/42989681/5535245). – georgeawg Mar 24 '17 at 20:33
  • The file upload code works great! – Leon Mar 28 '17 at 09:43

2 Answers2

3

You should use .then() instead of .success() to return your promise which you can then act upon and call the subsequent method.

Also, I'm curious as to why you wouldn't just update the DB server-side on your file-upload call.

Ben
  • 2,441
  • 1
  • 12
  • 16
  • this is only part of the file upload form. Files are uploaded asyncronously while the user is completing the form, and the IDs of the uploaded files are returned to the form. – Leon Mar 28 '17 at 10:00
1

no need to use $q to execute http requests in order. use promise chains to call the request after another

$scope.imageUpload = function() {
    var fd = new FormData();
    fd.append("file", $scope.imageFile);
    var data = fd;
    var url = 'http://myApiUrl';
    var postObject = {
        method: 'POST',
        url: url,
        data: data
    }
    return $http(postObject)
}
$scope.recordCreate = function(previousResponse) {
    var url = 'db_url';
    var postObject = {
        method: 'POST',
        url: url,
        data: previousResponse
    }
    return $http(postObject)
};
$scope.imageUpload()
    .then(function(response) {
        return $scope.recordCreate(response.data)
    })
    .then(function(response) {
        console.log(response.data);
    })
Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80