Handling Sequential AJAX Calls using jQuery

Two Successful Solutions and a Powerful Tool

Anantha Kashyap M D

Anantha Kashyap M D

Programmer Analyst
Anantha has over 7 years of experience in different Microsoft and Web technologies, including Web Forms, Win Forms, MVC Core, Web API Core, HTML5, JavaScript, jQuery, Angular 6, CSS3, Bootstrap 4, and Material Design. He likes to learn and experiment with new technologies and loves to teach others and share his knowledge and expertise.
Anantha Kashyap M D

Latest posts by Anantha Kashyap M D

The Problem

There is a requirement to make multiple AJAX calls parallelly to fetch the required data and each successive call depends on the data fetched in its prior call. Since AJAX is asynchronous, one cannot control the order of the calls to be executed. Because of this behavior, there is an inconsistency in the data that will be bound to the UI.

A Real-Life Example
Our team was working on an application that integrated all the reports created using Microsoft’s Power BI into it and the end users, based on their access levels, could view the reports and other related data. We also had a User Management System in place, from where Admins could manage other Users and restrict the data that they have to access.

In one of the screens, we have a requirement to display all the Available Reports in the system in one drop-down and all the Assigned Reports to a user in the other drop-down as shown in the below image.

Here we needed to make two AJAX calls to get the data for the above drop-downs. One call will fetch the assigned reports and then the other should be called to fetch all the available reports which will be filtered out based on the data that is already fetched in the first call to get the actual available reports.

Assigned Reports = Assigned Reports

Available Reports = Total Available Reports – Assigned Reports

Earlier, we were simply calling those functions one after the other.

Because of the asynchronous behavior, sometimes, getAvailableReports() function used to hit first which was resulting in fetching the inconsistent data to the Available Reports drop-downs as shown below.

Solutions

1. A Conventional Approach to this Issue

The easiest and simplest way to fix this issue is to call both the functions in sequence by nesting the getAvailableReports() into the success callback of getMappedReports() as shown in the below code
If there are multiple sequential AJAX calls to be made as shown in the below image, then the above approach makes the code less readable. This would lead to a lot of nested callbacks that have to be synchronized, which is often referred to as “callback hell.

2. A Generic and Re-Usable Approach

  • jQuery.when() provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events. jQuery.when() accepts deferreds (Deferred, Promise or Thenable objects)
  • As of jQuery 1.5, jQuery.Ajax() is a Promise-Compatible object meaning, it will return a resolved promise object
  • deferred.then() is a handler to be called when the deferred object is resolved, rejected or still in progress

Now, combining the above concepts, we can make two ajax requests one after the other as shown below.

However, there is a little problem. jQuery.when() function accept lists of arguments, so we have to pass them like this if we have multiple sequential ajax calls:

But what if we have hundreds of ajax calls to be made? We need a way to convert these ajax calls from jQuery.when() into a list of arguments. That’s where apply() function comes in handy.

When we call jQuery.when() function, “this” keyword inside the function is implicitly bind to jQuery object. But when we call jQuery.when.apply(), we have to explicitly bind “this” keyword to something. And we know that the binding has to be with jQuery object, so we pass jQuery object, a.k.a., $ as the first argument.

As we know that each jQuery.ajax() will return a deferred object, we can return a list of such deferred objects as an argument to jQuery.when.apply() as shown below. Now the solution looks more clean, readable, maintainable and a re-usable one.

Conclusion

Promises allow you to avoid nasty tricks to synchronize parallel or sequential asynchronous functions and the need to nest callbacks inside callbacks inside callbacks. Deferred remains an incredibly powerful tool to have in your toolbox. As a professional developer, and with the increasing difficulty of your projects, you’ll find yourself using it a lot.

References

.promise() – https://api.jquery.com/promise/

jQuery.Deferred() – https://api.jquery.com/jquery.deferred/

jQuery.when() – https://api.jquery.com/jquery.when/

deferred.then()https://api.jquery.com/deferred.then/

Share This Article


Anantha Kashyap M D

Anantha Kashyap M D

Programmer Analyst
Anantha has over 7 years of experience in different Microsoft and Web technologies, including Web Forms, Win Forms, MVC Core, Web API Core, HTML5, JavaScript, jQuery, Angular 6, CSS3, Bootstrap 4, and Material Design. He likes to learn and experiment with new technologies and loves to teach others and share his knowledge and expertise.
Anantha Kashyap M D

Latest posts by Anantha Kashyap M D

2 Comments
  • Supriya Rajgopal
    Posted at 06:11h, 12 June Reply

    I have had a personal experience facing the same problem & I had used the 1st approach (nesting) as there were only 2 ajax calls to be made.
    Using when() & apply() definitely looks cleaner, thanks for sharing this!

  • Jyothi Jaganath
    Posted at 08:45h, 12 June Reply

    Thank you for this simple, interesting article. It is indeed useful.

Post A Comment