Reputation: 15291
In my controller I have the following...
$scope.products = dataService.getJsonData();
console.log($scope.products);
and in my dataservice I have the following
.service('dataService', function ($http) {
this.getJsonData = function () {
return $http.get('path/to/json/products.json').then(function (response) {
// don't send back everything....
var productData = response.data;
console.log(productData);
return productData;
});
};
and in my view I have the following...
<div ng-repeat="product in products">
Name: {{ product.name }} <br>
Price: {{ product.price }}
<hr>
</div>
in my rendered view the repeat is showing only 3 items (products is an array of 15 objects). When looking at the console the repeat in the view or products is made of Object { then=function(), catch=function(), finally=function()}
but the log from the dataservice is out putting the desired object array. I don't understand why the output isn't waiting for the returned data, I thought this was asynchronous? How can I make the view wait for the dataservice without using a $timeout
. Has anyone else had this problem? Thanks in advance.
UPDATE *
From a bit of googling I'm pretty sure I need to add a resolve to my $routeProvider, the $routeProvider
currently looks like so:
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
resolve:{
// i need to put something here...
}
})
Upvotes: 2
Views: 4011
Reputation: 13725
With $resource it is a bit easier, like this:
dataService.factory('getJsonData', ['$resource',
function($resource) {
return $resource('path/to/json/products.json');
}
]);
The other parts are the same.
Upvotes: 1
Reputation: 10285
The actual update is happening in a callback, so you need to wrap it in $apply. Because it's happening in a service, you must use $rootscope
.service('dataService', function ($http,$rootScope) {
this.getJsonData = function () {
return $http.get('path/to/json/products.json').then(function (response) {
$rootScope.$apply(function () {
// don't send back everything....
var productData = response.data;
console.log(productData);
return productData;
})
});
};
From the angular promises docs
// since this fn executes async in a future turn of the event loop, we need to wrap our code into an $apply call so that the model changes are properly observed.
Edit: As OdeToCode pointed out, this is really not needed. The reason is that what http.get returns is an Angular promise, which is already doing an $apply internally on the .then() callbacks.
Upvotes: 0
Reputation: 344
hmm not sure if it will help, because angular is async but try adding this to your controller before using the data.
dataService.getJsonData().success(function (response){
$scope.products = response
})
Upvotes: 2
Reputation: 1667
When you call dataService.getJsonData()
it doesnt return the data that the $http.get returns, it returns a promise that will be fulfilled with the data in the future. I would recommend you to read up on promises. You can read about the angular implementation here.
As I mentioned, the function returns a promise that will be fulfilled, so you need to set the data in the scope when the promise is fulfilled. Change your controller to this:
dataService.getJsonData().then(function (products) {
$scope.products = products
})
Upvotes: 5