AngularJS execution order with `$q` -- Chaining Promises
Asked Answered
G

1

5

Following Approach works:

$q.when()
        .then(checkCookieToken)         // check if cookie already exists e.g. in cookie
        .then(setHeader)                // set Header with REST-Token e.g from cookie
        .then(checkTokenOnline)         // if not OK logout
        .then(getMenu)                  // if previous OK get navigation menu
        .then(getDataResource)          // set ngResource
        .then(getData);                 // and query it

4 Questions:

1) If e.g. checkTokenOnline is not OK, I don't want to execute the rest functions, how can I quit (exit, break, whatever,..) at this point?

2) How can I set some of them parallel and some of them serial ?

3) How can I transfer data between them?

4) How can I make the following function dependend from its previous result?

Guaco answered 16/12, 2015 at 23:32 Comment(0)
C
7

You are asking how to chain functions in promises.

3) How can I transfer data between them?

4) How can I make the following function depend on its previous result?

Return data (or a promise) for the next function in the chain:

var p2 = p1.then ( function (data) {
     var nextData = someFn(data);
     return nextData;
});

var p3 = p2.then ( function (nextData) {
     var nextData2 = someOtherFn(nextData);
     return nextData2;
});

//return for further chaining
return p3;

1) If e.g. checkTokenOnline is not OK, I don't want to execute the rest functions, how can I quit (exit, break, whatever,..) at this point?

To reject a promise, have your function throw an error. The chain will skip all the .then methods until you supply an error handler.

var p2 = p1.then ( function checkTokenOnline (response) {
             if ( isBadFn(response) {
                 throw error;
             } else {
                 return nextData;
             }
   }) .then ( someFn 
    ) .then ( someOtherFn
    ) .catch ( function (error) {
          // someFn and someOtherFn skipped
          //log error
          throw error;
   });

 //return for further chaining
 return p2;

2) How can I set some of them parallel and some of them serial ?

To make two functions run in parallel, make two promises. Use $q.all to wait for them both to complete.

var p1 = $q.when ( fn1() );
var p2 = $q.when ( fn2() );

var p3 = $q.all ( [p1, p2] );

var p4 = p3.then ( function (responseList) {
      var response1 = responseList[0];
      var response2 = responseList[1];
      return something;
}). catch ( function (error) {
      //log error
      throw error;
});

//return for further chaining
return p4;

Be aware that $q.all is not resilient. If any promise throws an error, the .then method will be skipped and only the first error will go to the .catch method.

The rule of thumb for functional programming is always return something.


Useful links

Conte answered 17/12, 2015 at 4:0 Comment(4)
Is .then() alwas available ? How is the correct syntax? return stands all alone in the code and it is not within curly brackets? Somehow irritating for PHP Programmers.Photometry
@Conte would you answer the question from Lonely Programmer ? That's good question, I think.. Thank you very much..Guaco
@LonelyProgrammer .then is a standard method for JavaScript promises . See the Promises/A+ Open Standard. Or specifically for AngularJS the AngularJS $q Service API Reference.Conte
@LonelyProgrammer AngularJS services that return promises include $q.when, $http, $timeout, $interval, all .then and .catch methods, many AngularJS custom modules and factory services and others.Conte

© 2022 - 2024 — McMap. All rights reserved.