Reputation: 2164
I have 2 $http
functions that I call using ng-init
because the data they return populates the page.
ng-init = "getOpen(); getClosed();"
Is this the best way?
First function;
$scope.getOpen = function () {
$http({
method: 'post',
url: "http://www.example.co.uk/php/open-get.php",
data: $.param({ 'location' : $scope.l,
'time' : $scope.t,
'day' : $scope.d,
'type' : 'get_restopen' }),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).
success (function(data, status, headers, config){
if(data.success && !angular.isUndefined(data.data) ){
$scope.open = data.data;
} else {
$scope.open = [];
}
}).
error(function(data, status, headers, config) {
//$scope.messageFailure(data.message);
});
}
Second function;
$scope.getClosed = function () {
$http({
method: 'post',
url: "http://www.example.co.uk/php/closed-get.php",
data: $.param({ 'location' : $scope.l,
'time' : $scope.t,
'day' : $scope.d,
'type' : 'get_restopen' }),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).
success (function(data, status, headers, config){
if(data.success && !angular.isUndefined(data.data) ){
$scope.closed = data.data;
} else {
$scope.closed = [];
}
}).
error(function(data, status, headers, config) {
//$scope.messageFailure(data.message);
});
}
Everything works great. My question I guess is this an efficient way of doing things in AngularJS? I'm new to angular so just seeking guidance.
1 - Are my $http
executed simultaneously? Or is one completed before the other one is started?
2 - Is there any need to introduce $q
or promises
into my code? The functions are independent of each other
3 - How can I detect when all $http
request have completed regardless of if successful or not
Is the below code correct?
$q.all([$scope.getOpen, $scope.getClosed]).then(function() {
//Both requests have been completed and I shall now set a bolean
$scope.compelete = true;
});
Upvotes: 0
Views: 530
Reputation: 11398
I have 2 $http functions that I call using ng-init because the data they return populates the page.
ng-init = "getOpen(); getClosed();"
Is this the best way?
As said into angular documentation :
This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit, such as for aliasing special properties of ngRepeat, as seen in the demo below; and for injecting data via server side scripting. Besides these few cases, you should use controllers rather than ngInit to initialize values on a scope.
You can find it here : https://docs.angularjs.org/api/ng/directive/ngInit
you should avoid using ng-init into your templates. The recommended usage for initiating something into a controller is to call a private function directly inside your controller.
I also recommend to read that style guide about angular :
https://github.com/johnpapa/angular-styleguide
1 - Are my $http executed simultaneously? Or is one completed before the other one is started?
The 2 calls are started almost simultaneously. Then, javascript holds a stack of callbacks he has to execute when he gets answers from your server. Just press F12 into your browser and find a "network" tab to see all your requests being launched.
Furthermore, ´.success´ is deprecated now. You should rather use ´.then´ https://docs.angularjs.org/api/ng/service/$http#deprecation-notice
2 - Is there any need to introduce $q or promises into my code? The functions are independent of each other
Not in this case. You could use $q.all([promise1, promise2])
if you wanted to execute something after both calls had been executed
3 - How can I detect when all $http request have completed regardless of if successful or not
Have a look at $httpInterceptors. Let share you a piece of code I implemented
angular.module("myModule").factory("myHttpInterceptor", [
"LoadingService",
"$q",
"Alert",
function (LoadingService, $q, Alert) {
function requestInterceptor(config) {
LoadingService.increaseCounter();
return config;
}
function responseInterceptor(response) {
LoadingService.decreaseCounter();
return response;
}
// ...
Is the below code correct?
$q.all([$scope.getOpen, $scope.getClosed]).then(function() { //Both requests have been completed and I shall now set a bolean $scope.compelete = true; });
nope because you still the promise to be returned by your function. Also, ´.success´ does not implement the chaining of promises. You now HAVE to use ´.then()´
$scope.getOpen = function () {
return $http({
// config
}).
then(function(data, status, headers, config){
//handling success
},(function(data, status, headers, config) {
//handling error
});
Summary :
angular.module("yourApp").controller("someController", ["$scope", "$q"
function($scope, $q){
// init
init();
// Shared functions
$scope.getOpen = function () {
return $http({
method: 'post',
url: "http://www.example.co.uk/php/open-get.php",
data: $.param({ 'location' : $scope.l,
'time' : $scope.t,
'day' : $scope.d,
'type' : 'get_restopen' }),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
$scope.getClosed = function () {
return $http({
// config
});
// private functions
function init(){
var promises = [];
promises.push($scope.getOpen());
promises.push($scope.getClosed());
$q.all(promises).then(function(datas){
// Here, you know both calls have been successfull
// datas[0] is the result of $scope.open()
$scope.open = datas[0].data;
$scope.complete = true;
}, function(errors){
$scope.complete = true;
// You fall here if one of your calls has failed
});
}
}
]);
Upvotes: 0
Reputation: 2313
$http is asynchronous, so your 2 calls should be executed in parallel. If you really need to boil the 2 functions down to one, and/or you need to check all $http requests have completed, you can use $q.all Angularjs $q.all
Upvotes: 0
Reputation: 19672
Assuming you call both methods yourself somewhere, yes. $http
calls are async by default
Already done, $http
actually returns a promise!
promise.all()
is an elegant way to do so without modifying the return of the promise. It is effectively a completion watcher. More details over on the promise reference
Upvotes: 1