In my Angular 1.5.8 app, I have different views that require various combinations of the same 3 ajax requests. Some views need data from all three endpoints, while others only need data from one or two.
To efficiently manage the retrieval of this data, I am developing a function that will ensure each endpoint is called only when necessary. I want the ajax requests to be triggered on demand and no sooner. While I have a working function in place, I believe it can be enhanced further.
The function below resides within the $rootScope
. It utilizes the fetchData()
function to cycle through the get requests as needed. Once data is fetched, it is stored in the global variable $rootScope.appData and then fetchData()
is invoked again. When all required data is obtained, the deferred promise is resolved and the data is returned to the controller.
$rootScope.appData = {};
$rootScope.loadAppData = function(fetch) {
var deferred = $q.defer();
function getUser() {
$http
.get('https://example.com/api/getUser')
.success(function(result){
$rootScope.appData.currentUser = result;
fetchData();
});
}
function getPricing() {
$http
.get('https://example.com/api/getPricing')
.success(function(result) {
$rootScope.appData.pricing = result;
fetchData();
});
}
function getBilling() {
$http
.get('https://example.com/api/getBilling')
.success(function(result) {
$rootScope.appData.billing = result;
fetchData();
});
}
function fetchData() {
if (fetch.user && !$rootScope.appData.currentUser) {
getUser();
} else if (fetch.pricing && !$rootScope.appData.pricing) {
getPricing();
} else if (fetch.billing && !$rootScope.appData.billing) {
getBilling();
} else {
deferred.resolve($rootScope.appData);
}
}
if ($rootScope.appData.currentUser && $rootScope.appData.pricing &&$rootScope.appData.billing) {
deferred.resolve($rootScope.appData);
} else {
fetchData();
}
return deferred.promise;
};
An object fetch
is passed as an argument indicating which ajax requests to trigger. For instance, calling $rootScope.loadAppData()
with only user and pricing data required would look like this:
$rootScope.loadAppData({user: true, pricing: true}).then(function(data){
//execute view logic.
});
I have a few questions:
- Could the chaining of functions be optimized? Is
fetchData()
adequate, or is there a better way to accomplish this functionality? - Is there a method to initiate all necessary Ajax requests simultaneously, yet wait for all calls to finish before resolving the promise?
- Is it common practice to store data in the
$rootScope
?
Note: Error handling is not implemented in this function at present. I plan to incorporate error handling prior to using this code snippet, although it's not directly related to my inquiry.