There are various methods to ensure only one HTTP call is made, but the options are limited due to the software versions being used.
One approach is to utilize a promise or configure your HTTP request to be sent only once. However, this feature is available in later versions of Angular. It's recommended to check the version you are using.
When it comes to best practices, utilize what your stack permits. There isn't a singular way to achieve a task. Best practices for asynchronous operations include utilizing callbacks, promises, HTTP settings, and most importantly, implementing what works within your current stack setup.
The factory code below implements a unique method to handle multiple callbacks for the same data. Subsequent calls to the factory will be added to the callbackStack until the initial HTTP request returns with the data. At that point, each callback will be triggered to retrieve the data.
angular.module('someApp').factory('operationService', ['$http', function($http){
var callbackStack = [];
var firstCallMade = false;
var factoryServerData;
return {
getOperations: getOperations
};
function getOperations( ctrlCallback ){
callbackStack.push( ctrlCallback );
if( firstCallMade ){ return; }
firstCallMade = true;
getOperationsHttpRequest();
};
function getOperationsHttpRequest(){
$http.get('some-link').success( factoryCallback );
}
function factoryCallback( operations ){
// Handle !operations here if necessary.
factoryServerData = operations || null;
callbackStack.forEach( giveCtrlCallbackResponse );
}
function giveCtrlCallbackResponse( ctrlCallback ){
ctrlCallback( factoryServerData );
}
}]);
By incorporating a callback in each controller, you can ensure that the response from the HTTP call is received. Even if an empty array is returned, it will be due to the server's response and not asynchronous issues with controller loading.
.controller('SomeController', ['$scope', 'operationService', function($scope, opService){
opService.getOperations( getOperationsCallback );
// The $scope.operations will wait until the server responds.
function getOperationsCallback( response ){
$scope.operations = response;
}
}]);
.controller('SomeOtherController', ['$scope', 'operationService', function($scope, opService){
opService.getOperations( getOperationsCallback );
// The $scope.operations will wait until the server responds.
function getOperationsCallback( response ){
$scope.operations = response;
}
}]);
NOTE: If nested controllers are being used, the first controller can initiate the call and then broadcast the results to all nested controllers as well. This can be captured using scope.$on....