I've just started using Angular with Ionic and so far it's great except for a problem with my ecommerce app where I am doing two ajax requests, one to load the vendor name and the other to load the products. I know I could put this in the same request but for other reasons it needs to be kept it separate.
Sometimes the vendor name gets set and sometimes it fails. It seems to be completely random and if I put a debugger in place it always works so appears to be something to do with timing.
.controller('VendorProductsCtrl', function($scope, $stateParams, $http) {
var vendor_name_url = 'URL FOR VENDOR NAME';
$http.get(vendor_name_url)
.success(function(response){
$scope.vendor_name = response.meta.vendor_name;
//debugger; this always works!
})
.error(function(data) {
console.log('server error');
})
$scope.products = [];
$scope.loadMore = function() {
var url = 'URL FOR PRODUCTS';
$http.get(url)
.success(function(response){
$scope.products = response.products;
})
.error(function(data) {
console.log('server error');
})
};
})
There seems to be something fundamental that I am missing on my new quest into Angular land. Thanks for your help.
P.S I'm using Ionic's infinite scroll which is calling loadMore()
Got it working, but seems a bit dodgy!
setTimeout(function () {
$scope.$apply(function () {
$scope.vendor_name = response.meta.vendor_name;
});
}, 500);
I'm not keen on waiting for 500ms or whatever it's set to if it's ready earlier, is there a better way?
Seems to be an issue with the http request for the vendor name being finished before the $scope
is applied when it works.
Move the definition of your $scope.vendor_name
outside of the promise callback.
$scope.vendor_name = '';
$http.get(vendor_name_url).success(function(response){
$scope.vendor_name = response.meta.vendor_name;
})
.error(function(data) {
console.log('server error');
});
loadMore()
works correctly because the $scope
has the variable of products = [];
during the wire-up of the controller. Everything after that hits the scope lifecycle of updating.
EDIT:
I would try to avoid doing the $scope.$apply
function as you will then start using it everywhere and it makes the maintenance of your services and controllers very difficult.
Another way to approach this issue is to use resolves on your route.
http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx
This is a great approach to getting multiple data pieces into your controller defined by the route. The wire-up of the controller by the route is responsible for ensuring that data is available for dependency injection on the controller when it runs.
Use $q.all
$q.all([
$http.get(vendor_name_url),
$http.get(url)
]).then(function(_responses){
$scope.vendor_name = _responses[0].meta.vendor_name;
$scope.products = _responses[1].products;
})