2

am facing problem in execution function in desired order.

$scope.function1 = function(){
   var promiseObj= $http.get('Some Url');

  /* other logic goes here */
}

$scope.function2 = function(){
   var promiseObj= $http.get('Some Url');

  /* other logic goes here */
}

$scope.function3 = function(){
   var promiseObj= $http.get('Some Url');

  /* other logic goes here */
}

Now, want to execute function in following order,

1) function1

2) function2

3) function3

And I want function2 and function3 to be executed only after function1 completes its execution.

I have tried the following approach,

$.when(
  $scope.function1()
).then(
   $scope.function2(),
   $scope.function3()
      )

Still, it didn't work . First function2 gets executed then function1

Vivek Verma
  • 293
  • 3
  • 16

3 Answers3

3
$.when(
   $scope.function1()
).then(
  $scope.function2(),
  $scope.function3()
)

You are passing result of execution to callback, while wanting to pass the whole code inside of then as a callback. The correct version will be:

$.when(
  $scope.function1()
).then(function () {
  $scope.function2(),
  $scope.function3()
})

$.when seems strange still. Why do you mix angular with something else? Just use:

$scope.function1().then(function () {
  $scope.function2(),
  $scope.function3()
})

Ensure that function1 returns promice.

Qwertiy
  • 19,681
  • 15
  • 61
  • 128
2

Your functions aren't returning anything but they need to return the $http promises.

Since they aren't returning promises $.when resolves immediately

Also no need to use jQuery when angular has $q promises built in and $http returns a $q promise

Functions need to look more like:

var function1 = function(){
   var promiseObj= $http.get('Some Url').then(function(response){
       var data = response.data;
       // do something to data here, and return it
       return data
   });    
   // return the promise
   return promiseObj; 
}

now you can do something like:

function1()
  .then(function2)
  .then(function3)

Or if the second and third can be sent simultaneously after the first:

function1().then(function(func1Data){
   // can use func1Data  here if needed since it was returned to prior `then()`
   function2();
   function3();
});

Also note no need to make these functions scope properties since they are not going to be passed to the view. Only use scope for view related objects

charlietfl
  • 170,828
  • 13
  • 121
  • 150
0

First thing: Your functions must return a promise like:

$scope.function1 = function(){
   var defer = $q.defer();
   var promiseObj= $http.get('Some Url');

   /* other logic goes here */
   defer.resolve(response);
   return defer.promise;
}

Or:

$scope.function1 = function(){
   return $http.get('Some Url');
}

Then you can chain your functions like this:

$scope.function1.then(function(response1) {
    $scope.function2.then(function(response2) {
        $scope.function3.then(function(response3) {
            // do some stuff
        }).catch(function(err){})
    }).catch(function(err){})
}).catch(function(err){})

There are also some strategires to flatten this chains, for more information read this.

Parav01d
  • 308
  • 2
  • 5
  • Why to use jQuery promice in angularjs application? Are you sure that you didn't miss some `$scope.$apply` calls in such case? – Qwertiy Nov 14 '16 at 10:47
  • Also, what about promise chaining? – Qwertiy Nov 14 '16 at 10:48
  • Using a new `$q.defer()` is a common anti-pattern when `$http` already returns a promise. See http://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it – charlietfl Nov 14 '16 at 10:53