$resource in angularjs does not work properly

All we need is an easy explanation of the problem, so here it is.

i’m trying to use angular with django i’ve implemented a REST api with django tastypie,
here’s the code for the angular resource:

angular.module('CourseServices', ['ngResource']).
    factory('Course', function($resource){
  return $resource('api/v1/course/:courseId/?format=json', {}, {
    query: {method:'GET', params:{courseId:'1'}, isArray:true}
  });
});

and here is where i’m trying to get it:

var course = Course.get({courseId:$routeParams.courseId});
console.log(course);

this code logs this in the browser:

Resource
course_pic: "http://localhost:8000/media/course_pics/2012/10/24/Apple-Launches-Genius-Recommendations-for-Apple-TV-2.png"
creation_time: "2012-10-24T06:28:11+00:00"
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed faucibus cursus mi, in laoreet dolor placerat vitae. ."
id: "1"
instructor: "/api/v1/user/1/"
name: "Computation Theory"
resource_uri: "/api/v1/course/1/"
subscribers: 0
update_time: "2012-10-24T06:28:11+00:00"
__proto__: Resource

so i have the data i want but when i try to access for instance “course.id” in my controller i get undefined! i have no idea why! the REST server response is json.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

To solve the problem you are having we need to understand the inner workings on $resource first. There is a question and a longer answer here, but in short we need to realize that $resource does asynchronous calls even if its syntax suggest that we are dealing with synchronous ones.

What is happening in your case is that when you are trying to access query data in your controller those data are not ready yet. Upon a call to the $resource AngularJS will just return an empty object (kind of placeholder) and will fill in data (properties) only when response comes back from the server.

Essentially what you are facing here is a timing issue. To work around this you can use a callback when invoking the query method, something along those lines:

var course; Course.get({courseId:$routeParams.courseId}, function(data){
    console.log(data);
    course = data;
    //course.id should be defined here 
});

So, once again: $resource methods are still asynchronous even if the syntax might suggest otherwise. You need to deal with the data in the success callback if you want to be sure that data are ready.

Method 2

it is true that $ resource is asynchronous, but you can bypass it turning into a delayed value object, look here, it’s may be help you.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply