2

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...
      }
  })
3
  • Do I need to add a resolve to my $routeProvider perhaps? Commented Mar 14, 2014 at 10:33
  • I think i usually add a callback to getJSONData to update $scope, instead of returning data Commented Mar 14, 2014 at 10:47
  • No, what you need is $apply. I fixed your code in my answer. Commented Mar 14, 2014 at 10:53

4 Answers 4

5

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
})
Sign up to request clarification or add additional context in comments.

Comments

2

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
})

Comments

1

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.

Comments

0

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.

1 Comment

Well, the $apply in the promises docs is only needed because it is using a setTimeout. What Mike needs is just a call to .then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.