Reputation: 1475
I have a React client app that needs to talk to a Rails API. I want to use the rails-ujs method Rails.ajax. For example:
Rails.ajax({
type: "POST",
url: "/things",
data: mydata,
success: function(response) {...},
error: function(response) {...}
})
It looks like I can't set data
to a JSON object like this:
mydata = {
thing: {
field1: value1,
field2: value2,
}}
I need to convert it to a application/x-www-form-urlencoded
content type manually like this:
mydata = 'thing[field1]=value1&thing[field2]=value2'
This is ok for flat data but gets complicated quickly for nested data.
jQuery does the conversion automatically before making a request.
So I'm wondering if Rails UJS has some automatic way of doing it, but I couldn't find anything in the docs or code.
Upvotes: 24
Views: 6811
Reputation: 4996
I noticed no actual solution for the stated problem, just workarounds.
Here is a link to a gist (JS class) that will handle the required serialization:
https://gist.github.com/dansimpson/231546
Upvotes: 0
Reputation: 7210
When using Rails UJS, data must be formatted as string form parameters. Unfortunately, it's not possible to provide JSON, at least not currently with Rails 6.0.2 (not ideal).
Use URLSearchParams
to convert JSON to URL paramaters:
myData = {
thing: {
field1: value1,
field2: value2,
}}
Rails.ajax({
type: "POST",
url: "/things",
data: new URLSearchParams(myData).toString()
})
Upvotes: 17
Reputation: 140
you can set the content type in your ajax call and sending the data in json format
var data={
user:{
first_name: firstname,
last_name: lastname,
username: username
}}
send the ajax call by placing content type as json in http header request
$.ajax({
type: "POST",
url: "http://someurl/post",
data:data,
contentType: "application/json",
success: function(data) {
-------
}
});
Upvotes: -1
Reputation: 402
Here is my workaround to put/post with Content-Type: application/json.
It works by setting options.data in the beforeSend callback. This way the internal Rails.ajax.createXHR method does not set the Content-Type header first. https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee#L53
Rails.ajax({
url: 'http://some-url.com',
type: 'put',
beforeSend(xhr, options) {
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8')
// Workaround: add options.data late to avoid Content-Type header to already being set in stone
// https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee#L53
options.data = JSON.stringify(data)
return true
},
});
Upvotes: 9
Reputation: 1518
Not sure if I'm misunderstanding the issue, but can't you just convert your object using JSON.stringify?
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
Certainly I can see in the rails-ujs module it's using JSON.parse to parse the Json response
Upvotes: 0
Reputation: 191
I reviewed the library code and It doesn't support that because in order to send an object you have to stringify the object, and after doing that I discovered that the library checks if the data is the type of string It changes the content type of the request to application/x-www-form-urlencoded . This link shows that condition in the library. And for that, your option to overcome this issue is to write a method that transforms the object to input form way or use JQuery Ajax or another library.
Upvotes: 1
Reputation: 3233
I used ajax call several times and I used to send json data like this.
var fd = new FormData();
fd.append("jsondata", JSON.stringify(mydata));
$.ajax({
url: ...
type :"post",
data: fd
success:function(){
}
})
Parsing Json data in ruby controller is easy.
you can just use JSON.parse(params["jsondata"])
Hope this works for your case.
Upvotes: 7