Question

I am using angularjs and spring rest service. its a very simple scenario but dont know whats the issue!

This is my controller where in it returns array of daya defined in service.js. In below code, console returns 0 always.

controller.js

$scope.allreviews = PostFactory.reviews.query({key: reviewId});
    console.log('read more' + $scope.allreviews.length);

services.js

reviews: $resource('/ngdemo/web/posts/review/:key', {}, {
        query: {method: 'GET', isArray: true, params: {key: '@key'} },
        create: {method: 'POST'}
    })

now, the rest service defined in reviews method"/ngdemo/web/posts/review/:key" returns data as I can see in Firefox console GET method. but it doesnt reach controller, hence cant access the data. Could you please help suggesting whats the issue?

I tried removing isArray: true but it throws error $destination.push is nt a function or something error.

Please suggest

Was it helpful?

Solution

The issue you are facing is relevant to asynchronous nature of $resource. Every time you assign resource query to some property of scope, you actually assign some kind of empty object that will be populated once relevant response will come. Therefore you can't access data directly in a synchronous manner. There are several different ways that allow you to access data once it has come. Here are two possible ways (using callback function as argument of query and $scope.$watch()):

JavaScript

angular.module('app',['ngResource']).
  controller('PostController',['$scope', 'PostFactory', function($scope, PostFactory) {
    var reviewId = 'post.json';

    $scope.allreviews = PostFactory.reviews.query({key: reviewId}, function(allreviews) {
      console.log('(callback) read more ' + $scope.allreviews.length); // <= will log correct length
    });

    console.log('read more ' + $scope.allreviews.length); // <= will always log 0


    $scope.$watch('allreviews.length', function(length) {
      if(length) { // <= first time length is changed from undefined to 0
        console.log('(watch) read more ' + $scope.allreviews.length); // <= will log correct length
      }
    });
  }]).
  factory('PostFactory', ['$resource', function($resource) {
    return {
      reviews: $resource(':key', {}, {
        query: {method: 'GET', isArray: true, params: {key: '@key'} },
        create: {method: 'POST'}
      })
    }
  }]);

Plunker: http://plnkr.co/edit/vy52X0lJkGSL4neSeNUy?p=preview

OTHER TIPS

You have to wait for your query to finish before logging out the result. From the angular docs:

It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data.

So you could do something like this

$scope.allreviews = PostFactory.reviews.query({key: reviewId} function() {
    console.log('read more' + $scope.allreviews.length);
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top