Making parallel API calls using $q.all()

Loading

What You’ll Learn:

What is $q.all()?
Why use $q.all() for parallel API calls?
Step-by-step implementation
Real-world example: Fetching multiple API responses in parallel
Handling success and error cases


1️⃣ What is $q.all()?

🔹 $q.all() is a method in AngularJS’s $q service that handles multiple asynchronous operations in parallel.
🔹 It takes an array (or object) of promises and resolves when all promises are completed.
🔹 It is useful when you need data from multiple sources before proceeding further.


2️⃣ Why Use $q.all() for Parallel API Calls?

Efficiency – Instead of calling APIs sequentially, $q.all() allows you to execute them simultaneously, reducing wait time.
Data Dependency – If your application requires multiple data sources at once, $q.all() ensures all data is available before proceeding.
Cleaner Code – Instead of nesting multiple callbacks, $q.all() makes the code more readable and maintainable.


3️⃣ Basic Syntax of $q.all()

$q.all([promise1, promise2, promise3]).then(function (responses) {
var response1 = responses[0];
var response2 = responses[1];
var response3 = responses[2];

console.log(response1, response2, response3);
});

🔹 $q.all() takes an array of promises and resolves when all are completed.
🔹 The responses array contains the results of all promises in order.


4️⃣ Step-by-Step Implementation

Scenario: Fetching User Details & User Orders Simultaneously

Imagine an e-commerce website where we need:

  • GET /api/user/1User Details
  • GET /api/orders?userId=1User Orders

Instead of calling them one after another, we fetch them in parallel using $q.all().


🔹 Step 1: Define API Calls in a Service

Create an AngularJS service that fetches data using $http.

javascriptCopyEditapp.factory("ApiService", function ($http) {
    return {
        getUser: function () {
            return $http.get("/api/user/1"); // Returns a promise
        },
        getOrders: function () {
            return $http.get("/api/orders?userId=1"); // Returns a promise
        }
    };
});

🔹 Step 2: Use $q.all() in Controller

Inject $q and ApiService into a controller and call APIs in parallel.

app.controller("MainController", function ($scope, $q, ApiService) {
// Call both API requests in parallel
$q.all([ApiService.getUser(), ApiService.getOrders()])
.then(function (responses) {
// responses[0] -> User details
// responses[1] -> Orders data
$scope.user = responses[0].data;
$scope.orders = responses[1].data;
})
.catch(function (error) {
console.error("Error fetching data:", error);
});
});

🔹 $q.all([ApiService.getUser(), ApiService.getOrders()]) starts both requests at the same time.
🔹 Once both requests finish, .then() executes, storing the results in $scope.user and $scope.orders.
🔹 If any request fails, .catch() handles the error.


🔹 Step 3: Display Data in HTML

<div ng-controller="MainController">
<h2>User Info</h2>
<p>Name: {{ user.name }}</p>
<p>Email: {{ user.email }}</p>

<h2>Orders</h2>
<ul>
<li ng-repeat="order in orders">
Order ID: {{ order.id }} - Amount: {{ order.amount }}
</li>
</ul>
</div>

The page only loads after both API calls are complete.


5️⃣ Handling Success and Error Cases

Case 1: When All Requests Succeed

If all API calls return successfully, the .then() function receives the responses in the same order as the promises.

$q.all([ApiService.getUser(), ApiService.getOrders()])
.then(function (responses) {
console.log("User Data:", responses[0].data);
console.log("Orders Data:", responses[1].data);
})
.catch(function (error) {
console.error("Something went wrong:", error);
});

Case 2: If One API Fails

If any API request fails, $q.all() immediately rejects, and .catch() handles the error.

$q.all([ApiService.getUser(), ApiService.getOrders()])
.then(function (responses) {
console.log("Data fetched successfully:", responses);
})
.catch(function (error) {
console.error("API call failed:", error);
});

Solution: Handle Errors Individually

Use .catch() for each API to avoid stopping all requests if one fails.

$q.all([
ApiService.getUser().catch(() => ({ data: { name: "Unknown", email: "N/A" } })),
ApiService.getOrders().catch(() => ({ data: [] }))
]).then(function (responses) {
$scope.user = responses[0].data;
$scope.orders = responses[1].data;
});

6️⃣ Alternative: Using Object Format in $q.all()

Instead of an array, you can pass an object to $q.all(), which makes response handling easier.

$q.all({
user: ApiService.getUser(),
orders: ApiService.getOrders()
}).then(function (responses) {
$scope.user = responses.user.data;
$scope.orders = responses.orders.data;
});

🔹 Responses are accessed using responses.user and responses.orders instead of using array indexes.


7️⃣ Summary of $q.all()

FeatureDescription
Executes API calls in parallelRuns multiple API requests at the same time
Resolves when all promises completeWaits for all responses before executing .then()
Rejects if any API failsIf one fails, it triggers .catch()
Supports array/object inputsAccepts both array ([]) and object ({}) formats
Improves efficiencyReduces total wait time for multiple API calls

Leave a Reply

Your email address will not be published. Required fields are marked *