Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular JS ngResource with nested resources

I'm trying out angular JS and I want to get data from a nested resource defined in my rails application.

I wrote the following lines:

UserMission = $resource("/users/:user_id/user_missions/:id", {user_id: "@user_id", id: "@id"}, {update: {method: "PUT"}})
$scope.user_missions = UserMission.query()

and I get the following error:

  Processing by UsersController#show as JSON
  Parameters: {"id"=>"user_missions"}
  User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", "user_missions"]]
Completed 404 Not Found in 10ms

ActiveRecord::RecordNotFound (Couldn't find User with id=user_missions):
  app/controllers/users_controller.rb:100:in `current_resource'
  app/controllers/application_controller.rb:34:in `authorize'

My rails routes are organized like so:

resources :users do
  resources :user_missions
end

I think it comes down to me not understanding "@id". It says it comes off of the "data object" from the angularjs site and I am not exactly sure what that means.

Any help would be appreciated thanks.

Update

Another question. I have not found any examples of rails with angularjs using nested resources (an example User has_many :missions, through: :user_missions ) with $resource. Is there a good example of angularjs manipulating nested resources (with $resource) with ajax?

like image 605
GTDev Avatar asked Feb 25 '13 00:02

GTDev


2 Answers

Read through my answer to your previous question, you should include the values for both the parameters in an object you pass as a parameter in the call, i. e.:

$scope.user_missions = UserMission.query({user_id: some_value, id: some_other_value});
like image 102
remigio Avatar answered Oct 09 '22 04:10

remigio


I was also looking for a way to handle nested resources with ngResource. I am not familiar with how rails works or what your data looks like but this is what I had:

{"num_results": 5, "objects": [....], "page": 1, "total_pages": 1}

I needed to reach in and grab the nested objects array for the query action. Using the 1.0 version of angular this is not possible. However, with the 1.1 version (I tested with 1.1.3) it is possible to do this.

In my controller I just setup the resource like this:

$scope.MyModel = $resource("/api/mymodel/:id",
    {},
    {'query': {method: 'GET', isArray: true, "transformResponse": function (data) {
        return JSON.parse(data).objects;
    }}});

The key here is the transformResponse function passed as part of the action config. In 1.1 any extra config items in the action config are passed down into the $http config for the request. The $http service allows a transformResponse function that can manipulate the data returned by the request. Using this function I can reach into the nested structure and return the array I need for the action.

One caveat to notice here is that the transformResponse function receives a string value, so you must first parse the data into what you are expecting. The other caveat is that you return the actual final data value you want, NOT a string. Even though you receive a string value you should return the end data value required.

like image 10
bpedman Avatar answered Oct 09 '22 05:10

bpedman