Reputation: 1069
First of all, I am not good at angularjs.
While I've been studying about $q, I faced a weird problem.
When I use $q.all, I put $http in regular sequence expecting to get results in same order,
but what I get was random results.
See this and correct my stupidity.
$q.all([
HttpService.editItem(
$scope.$parent.category_id, // category id
Define.CAR_CAT, // category url to request
$scope.car_id, // car_id wanna edit
{car_name: inputValue.toUpperCase()} // data
),
HttpService.getCarList(
$scope.$parent.category_id, // category id
Define.CAR_CAT // category url to request
)
]).then(function (results) {
if (results[0].statusText === 'OK' && results[1].statusText === 'OK') {
.....
});
'HttpService' is a service of my app. It returns promise.
What I expected was
edit car name first, get car list later.
But results I got was get car list first, edit car name later.
And I'm using
return $q(function(resolve, reject){ });
instead of using
$q.defer();
.
.
.
.
and these are my HttpService part
function editItem(cat_id, cat_url, content_id, item_data) {
return $q(function (resolve, reject) {
$http({
method: 'PUT',
url: Define.TEST_URL + cat_id + cat_url + content_id,
data: item_data
}).then(function (response) {
resolve(response);
}, function (error) {
reject(error);
});
});
}
function getCarList(cat_id, cat_url) {
return $q(function (resolve, reject) {
$http({
method: 'GET',
url: Define.TEST_URL + cat_id + cat_url
}).then(function (response) {
resolve(response);
}, function (error) {
reject(error);
});
});
}
and here is the getCarList response
{
"error_msg": "",
"error_num": 0,
"statusText": "OK"
"results": [
{
"car_id": "CAR0121",
"car_name": "AUDI R8"
},
{
"car_id": "CAR0122",
"car_name": "AUDI A6"
},
{
"car_id": "CAR0128",
"car_name": "BENZ"
},
{
"car_id": "CAR0130",
"car_name": "PORCHE"
},
]
}
Upvotes: 5
Views: 4683
Reputation: 7179
If you want the calls to be sequential, you'll need to call them by using promise chaining instead of $q.all
HttpService.editItem(
$scope.$parent.category_id, // category id
Define.CAR_CAT, // category url to request
$scope.car_id, // car_id wanna edit
{car_name: inputValue.toUpperCase()} // data
)
.then(function(result) {
if (result.statusText === 'OK') {
return HttpService.getCarList(
$scope.$parent.category_id, // category id
Define.CAR_CAT // category url to request
)
}
else {
return $q.reject();
}
})
.then(function (result) {
if (result.statusText === 'OK') {
.....
});
Upvotes: 4
Reputation: 77910
Is there an method order in $q.all in Angularjs?
Yes, the Order is regards to Promises order you gave it to $q.all()
From ref: $q.all()
Returns a single promise that will be resolved with an array/hash of values, each value corresponding to the promise at the same index/key in the promises array/hash. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value.
var promises = [promise1(), promise2(), promise3()];
$q.all(promises).then((values) => {
console.log(values[0]); // value promise1
console.log(values[1]); // value promise2
console.log(values[2]); // value promise3
});
var promises = {one: promise1(), two: promise2(), three: promise3()};
$q.all(promises).then((values) => {
console.log(values.one); // value promise1
console.log(values.two); // value promise2
console.log(values.three); // value promise3
});
But results I got was get car list first, edit car name later.
I suggest you to create map approach and test what you get:
$q.all({edit:
HttpService.editItem(
$scope.$parent.category_id, // category id
Define.CAR_CAT, // category url to request
$scope.car_id, // car_id wanna edit
{car_name: inputValue.toUpperCase()} // data
),
getCar: HttpService.getCarList(
$scope.$parent.category_id, // category id
Define.CAR_CAT // category url to request
)
}).then(function (results) {
// results.edit
// results.getCar
});
EDIT
Upvotes: 7
Reputation: 45106
but what I get was random results.
$q.all
will await for promises running concurrently. So there is no guarantee which request hits server first. But the order of responses will be kept.
If you want to make sure you read after write you have to wait for write response to respond it was ok
var editing = HttpService.editItem(
$scope.$parent.category_id, // category id
Define.CAR_CAT, // category url to request
$scope.car_id, // car_id wanna edit
{car_name: inputValue.toUpperCase()} // data
)
var reading = editing.then(function() {
return HttpService.getCarList(
$scope.$parent.category_id, // category id
Define.CAR_CAT // category url to request
)
})
//if you need both results
$q.all([editing, reading]).then(function(results) {
})
Upvotes: 3