Promises chaining in AngularJS

Posted By : Mohd Adnan | 30-Jun-2017

With the introduction of Single Page Applications (SPA), way of designing the web applications took a huge transform. As said, everything comes with pros and cons, so does SPA. The one of major advantage of SPA is the ultra responsive websites. SPA runs on single threaded event loop, which handles all the tasks.
Here comes the tricky part is that single threaded events does not wait for tasks to finish and move on to the next task.

Problem: You've to perform tasks and n number of network calls(promises) parallelly in Angular Js. To solve this there is a traditional way of chaining callback functions together to achieve the desired task or there is an efficient way, which uses $q.all().

Solution: $q.all()

Consider that all of the functions in the following examples follow this format:

function promiseP() {
    let deferred = $q.defer();

    ajaxCall().then((response) => {
        deferred.resolve(response);
    }, (error) => {
        deferred.reject(error);
    });

    return deferred.promise;
}

 

Now Consider the way of chaining callbacks the promise results.

let values = [];
promiseAlpha().then((value1) => {
    values.push(value1);
    promiseBeta().then((value2) => {
        values.push(value2);
        promiseGamma().then((value3) => {
            values.push(value3);
            finish();
        });
    });
});

The problem here is as you can see is it will be difficult to 
i) get the resolved value of each promise and use it and

ii) chain more than a few promises without boilerplate. Here comes an alternative in the form of $q.all().

The

 $q.all() method takes either an object or an array of promises and waits for all of them to completely resolve() or one of them to reject() and then executes the provided callback function.

The return type depends if you provide $q.all() as promises of an array, then the values will be available as an array with the respective order of the promises array. Example:

let promisesArray = [promiseAlpha1(), promiseBeta1(), promiseGamma1()];

$q.all(promisesArray).then((values) => {
    console.log(values[0]); // value alpha1
    console.log(values[1]); // value beta1
    console.log(values[2]); // value gamma1

    finish();
});

Hence, if you provide an object to all(), the values are attached to an object with the respective property names in the all() callback.

let promises = {
    alpha: promiseAlpha(),
    beta: promiseBeta(),
    gamma: promiseGamma()
}
$q.all(promises).then((values) => {
    console.log(values.alpha); // value alpha
    console.log(values.beta); // value beta
    console.log(values.gamma); // value gamma

    finish();
});

PS: If you've to make network calls in Angular sequentially where the response of each API is dependent on other $q.all() is not the efficient way. Callbacks should be used in that case for chaining promises

 

 

About Author

Author Image
Mohd Adnan

Adnan, an experienced Backend Developer, boasts a robust expertise spanning multiple technologies, prominently Java. He possesses an extensive grasp of cutting-edge technologies and boasts hands-on proficiency in Core Java, Spring Boot, Hibernate, Apache Kafka messaging queue, Redis, as well as relational databases such as MySQL and PostgreSQL. Adnan consistently delivers invaluable contributions to a variety of client projects, including Vision360 (UK) - Konfer, Bitsclan, Yogamu, Bill Barry DevOps support, enhedu.com, Noorisys, One Infinity- DevOps Setup, and more. He exhibits exceptional analytical skills alongside a creative mindset. Moreover, he possesses a fervent passion for reading books and exploring novel technologies and innovations.

Request for Proposal

Name is required

Comment is required

Sending message..