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/1
→ User DetailsGET /api/orders?userId=1
→ User 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()
Feature | Description |
---|---|
Executes API calls in parallel | Runs multiple API requests at the same time |
Resolves when all promises complete | Waits for all responses before executing .then() |
Rejects if any API fails | If one fails, it triggers .catch() |
Supports array/object inputs | Accepts both array ([] ) and object ({} ) formats |
Improves efficiency | Reduces total wait time for multiple API calls |