$resource in angularjs does not work properly-Collection of common programming errors

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.

  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.

  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.