50

I am trying to send a jquery ajax PUT request that looks like this:

$.ajax({
          type: "PUT",
          url: '/admin/pages/1.json',
          data: { page : {...} },
          dataType: 'json',
          success: function(msg) {
            alert( "Data Saved: " + msg );
          }
});

but I get the following error:

The error occurred while evaluating nil.name
    /Library/Ruby/Gems/1.8/gems/activesupport-2.3.2/lib/active_support/xml_mini/rexml.rb:29:in `merge_element!'
    /Library/Ruby/Gems/1.8/gems/activesupport-2.3.2/lib/active_support/xml_mini/rexml.rb:18:in `parse'
    (__DELEGATION__):2:in `__send__'
    (__DELEGATION__):2:in `parse'
    /Library/Ruby/Gems/1.8/gems/activesupport-2.3.2/lib/active_support/core_ext/hash/conversions.rb:154:in `from_xml' ... ...

Is like Rails is trying to parse the params as XML, but I want to use JSON!!

What shall I do to put JSON to rails?

6 Answers 6

85

PUT and DELETE are not supported by all browsers, RubyOnRails supports passing an extra parameter with your data called _method which will indicate how RoR will treat the request.

$.ajax({
          type: "POST",
          url: '/admin/pages/1.json',
          data: { _method:'PUT', page : {...} },
          dataType: 'json',
          success: function(msg) {
            alert( "Data Saved: " + msg );
          }
});
Sign up to request clarification or add additional context in comments.

9 Comments

That doesn't seem to be the issue here (and do any modern web browsers really lack support for PUT?). The server /is/ receiving the data, just not parsing it the right way.
yes most browsers lack PUT and DELETE, only GET and POST. The server could be getting the data on the wrong action, ie. if its a POST it would normally map to the Create action and a PUT would map to the Update action.
annevankesteren.nl/2007/10/http-method-support would have me believing otherwise (i.e. that a lot of browsers actually do support PUT and DELETE).
The data is wrong and dataType is not what needs to be set. Lost an hour because of this answer.
@pascalbetz: The correct answer is lqc's. This answer will not make Rails parse this request as json, it will only return json.
|
37

The dataType param in jQuery isn't what you send, but rather specifies the format you expect the answer to be (yes, that's a very poor name). If you want to send your data to the server in a format other then application/x-www-form-urlencoded you should use contentType param. You also need to serialize your data:

$.ajax({
      type: "PUT",
      url: '/admin/pages/1.json',
      data: JSON.stringify({...}),
      contentType: 'application/json', // format of request payload
      dataType: 'json', // format of the response
      success: function(msg) {
        alert( "Data Saved: " + msg );
      }
});

Comments

5

Ok, actually my JSON data didn't have the page key, my mistake. So thats why it was not correctly parsing. But now I get "[object Object]" string as the value for page key instead of a nicely parsed json object.

Where should I look: JQuery or Rails?

EDIT:

I've solved my issue stringifying the json object with a script found here: www.json.org/js.html:

$.ajax({
      type: "PUT",
      url: '/admin/pages/1.json',
      data: { page : JSON.stringify( {...} ) },
      dataType: 'json',
      success: function(msg) {
        alert( "Data Saved: " + msg );
      }
});

On the rails side json gem must be required. In the controller:

 params[:page] = JSON.parse params[:page] if params[:page].is_a? String

3 Comments

I get JSON.strigify not defined, is there a JQuery lib to include?
That's a typo. It should be "stringify".
My issue is even though the database is being updated the request stays pending.
2
var id = $('#route_id').val()
$.ajax({
    type: 'PUT',
    url:  '/routes/'+ id,
    data: $('#markerform').serializeArray(),
    dataType: "JSON",
    success: function(data) {
        console.log(data);
    }
});

Comments

1

I had a similar problem [object Object] with jQuery/rails, but with HTML, rather than JSON. Perhaps this will help -

param of [object Object]

data: { lesson: { date: drop_date } }

param of lesson[date]

data: { "lesson[date]": drop_date }

hope this helps -

Comments

0

You probably just need to set the Request Headers on jQuery.

jQuery.ajaxSetup({ 
  'beforeSend': function(xhr) {
    xhr.setRequestHeader("Accept", "text/javascript");
  }
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.