Reputation: 1322
I am making a GET request on an paginated endpoint, therefore, I am making one call, finding out how many pages the endpoint has, then looping through each page, pushing the response data from each page into one array.
However, since the call is so large, when grabbing this factory data from my controller, I've needed to put a timeout on my function to make sure all the data has come in before it is used.
I was hoping to switch this over to a promise in my factory that the controller would wait for until the request is complete. But since I am looping through each page, the way I would normally structure this doesn't work. How could I rework this to make the promise wait for the complete loop through my endpoint's pages so I can remove the timeout from my controller?
Factory API GET request
var productsData = [];
var pageNumber = 1;
var getAllProducts = function(){
var deferred = $q.defer();
return $http.get('/api/scroll?page=' + pageNumber,{cache: true})
.then(function(response) {
for (var i = response.data.results.length - 1; i >= 0; i--) {
productsData.push(response.data.results[i]);
};
while (pageNumber <= response.data.pages) {
getAllProducts();
pageNumber++;
}
deferred.resolve(productsData)
return deferred.promise;
});
};
Controller Function
var filterProducts;
var getProducts = function(type, filter) {
productFactory.getAllProducts()
.then(function(products) {
$timeout( function(){
var allProducts = products;
switch (type) {
case "category":
filterProducts = $filter('filter')(allProducts, {
custom: {category_code: filter}
});
break;
case "color":
filterProducts = $filter('filter')(allProducts, {
custom: {color_code: filter}
});
break;
case "season":
filterProducts = $filter('filter')(allProducts, {
custom: {season: filter}
});
break;
default:
filterProducts = allProducts;
}
$rootScope.products = _.sortBy(filterProducts, function(product) {
return product.custom.sku;
});
}, 1000);
});
};
Upvotes: 0
Views: 2201
Reputation: 726
You should create a deferred object outside the GET call function and resolve it only after all requests are done. So i think it can look something like this
var productsData = [];
var pageNumber = 1;
var deferred;
function getAllProducts() {
deferred = $q.defer();
_getPageProducts(pageNumber);
return deferred.promise;
}
function _getPageProducts(pageNumber) {
$http.get('/api/scroll?page=' + pageNumber,{cache: true})
.then(function(response) {
for (var i = response.data.results.length - 1; i >= 0; i--) {
productsData.push(response.data.results[i]);
};
if (pageNumber < response.data.pages) {
pageNumber++;
_getPageProducts(pageNumber);
} else {
deferred.resolve(productsData) ;
}
});
}
Upvotes: 2