mhenrixon
mhenrixon

Reputation: 6278

How to serialize params in AngularJS $resource to a rails 3.2 compatible params

I am trying to get angular resource to serialize my object properly to a rails 3.2 controller action. The data format is JSON and the working and required input (on Rails side) should be:

"data"=>[{"id"=>29, "column"=>0, "position"=>0}], "id"=>"2", "page"=>{}

This works with our old code:

$.ajax
  type: "put"
  url: target
  dataType: "json"
  contentType: "application/json"
  data: JSON.stringify({data: widgets})

However if I try with angular resource I get something like below instead:

"data"=>"[{\"id\":28,\"column\":2,\"position\":0}]", "id"=>"2", "page"=>{"id"=>"2"}

I first created a factory:

app.factory "Page", ["$resource", ($resource) ->
  $resource "/admin/pages/:collectionRoute:id/:memberRoute",
  {
    id: "@id",
    memberRoute: "@memberRoute",
    collectionRoute: "@collectionRoute",
  },
  {
    update: {method: "PUT"}
    store_widgets: { method: "PUT", params: { data: "@data", memberRoute: 'store_widgets' }, isArray: true }
  }
]

... and called the store_widgets function with:

Page.store_widgets(id: $scope.page_id, data: JSON.stringify(widgets) )

I've tried a few alternatives to setting the data parameter but it doesn't seem to work. It's either posted as [Object object] or as plain string.

Any suggestions on how I might get the request sent by $resource to be exactly like the one that is working using pure jQuery Ajax?

Upvotes: 1

Views: 4183

Answers (3)

Viktor Ivliiev
Viktor Ivliiev

Reputation: 1334

This problem is solved in the 2.0 version of angular(

look here: https://github.com/angular/angular.js/issues/3740

Upvotes: 0

n3wbsauce
n3wbsauce

Reputation: 51

The only way was I able to solve serializing my parameters so I could see the data in a PHP POST channel was to use JQuery.param().

I had to set the header in my $resource:

headers : {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}

My call to $resource methods. This is quick and dirty so please forgive.

vm.save = function(item) { 
  var data = $.param({username:item.username, email:item.email});
  userFactory.save(data);
}

I had to pull the data out of item since $resouce attached methods to item. If you use $.param on item it ended up firing all the DELETE, GET, QUERY, etc.. methods attached to the resource.

Upvotes: 1

Stewie
Stewie

Reputation: 60416

Depending on whether you want data to be passed in request body or in query params:

In query params:

// 'store_widgets' action definition
store_widgets: {
  method: "PUT",
  params: {
    id: "@id",
    data: "@data",
    memberRoute: 'store_widgets'
  },
  isArray: true
}

Call:

function MyCtrl($scope, Page) {

  $scope.widget = [
    {"id":29, "column":0, "position":0}
  ];

  Page.store_widgets({id: 2, data: $scope.widget, page: {}});

}

Plunker.


In request body:

Call:

Page.store_widgets({id: 2, page: {}}, {data: $scope.widget});


Ass $resource docs say:

The action methods on the class object or instance object can be invoked with the following parameters:

  1. HTTP GET "class" actions: Resource.action([parameters], [success], [error])
  2. non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
  3. non-GET instance actions: instance.$action([parameters], [success], [error])

Upvotes: 1

Related Questions