Joe
Joe

Reputation: 4234

Using chained promises ($q) to make $http

I have data that I want to be "reverify". So I need to make a get request, save the data from the callback, delete the current data, then make a post with the data from the callback.

I need to use $q somehow.

Maybe I'm totally off but here's what i tried.

$scope.reSaveBIM = function(){

  var defer = $q.defer();

  defer.promise
    .then(function(){
      $http.get('/api/bim/' + $scope.activePartOfBim._id)
        .success(function(fullBIM){
          console.log(fullBIM); //Defined
          return fullBIM;
        }
      );
    })
    .then(function(fullBIM){
      console.log(fullBIM); //Undefined
      $http.delete('/api/bim/' + $scope.activePartOfBim._id);
      return fullBIM
    })
    .then(function(fullBIM){
      $http.post('/api/bim', {bim:JSON.stringify(fullBIM)});
    });

  defer.resolve()

};

The data from the first callback is not returned in the chained. Am I on the right track? I also tried to use $q.all but failed.

Any ideas?

Upvotes: 0

Views: 143

Answers (3)

Anthony Chu
Anthony Chu

Reputation: 37520

There's no need to create an additional $q.defer object, you can simply chain the promise returned by $http...

$scope.reSaveBIM = function() {
    return $http.get('/api/bim/' + $scope.activePartOfBim._id).then(function(response) {
        var fullBIM = response.data;
        return fullBIM;
    }).then(function(fullBIM) {
        return $http.delete('/api/bim/' + $scope.activePartOfBim._id).then(function() {
            return fullBIM;
        });
    }).then(function(fullBIM) {
        return $http.post('/api/bim', { bim:JSON.stringify(fullBIM) }).then(function() {
            return fullBIM;
        });
    }).catch(function(response) {
        // return an error message using throw
        throw "Something went wrong - Status " + response.status;
    });
};

To call it...

$scope.reSaveBIM().then(function(fullBIM) {
    console.log('success! fullBIM: ', fullBIM);
}, function(errorMsg) {
    console.log(errorMsg);
});

Upvotes: 1

Noah Solomon
Noah Solomon

Reputation: 1261

AngularJS's $http already wraps the $q service. From the documentation:

The $http API is based on the deferred/promise APIs exposed by the $q service.

Essentially your problem is that $http uses a different promise than the one you are creating with $q. You need chain your $http calls to do the same thing. The fact is, you are already using promises from $q.

Furthermore, you can flatten this out by declaring functions and passing them in as variables.

$http.get('/api/bim/' + $scope.activePartOfBim._id)
    .success(firstSuccessFunction);

var firstResponse;
var firstSuccessFunction = function(fullBIM){
  console.log(fullBIM); //Defined
  firstResponse= fullBIM;
  $http.delete('/api/bim/' + $scope.activePartOfBim._id)
          .success(secondSuccessFunction);
};

var secondSuccessFunction = function(deleteResponse) {
  $http.post('/api/bim', {bim:JSON.stringify(firstResponse)});
};

Upvotes: 0

Chandermani
Chandermani

Reputation: 42669

You are almost right, and you don't need defer. Instead of success use then. I think success does not return promise. Also $http then success callback has data in response.data property.

Upvotes: 0

Related Questions