I thought that Rails automatically identifies/parses JSON params if the request is recognized as JSON. But the request below:
Processing by Api::V1::LinksController#create as JSON
Parameters: {"link"=>"{\"title\":\"My first title\"}"}
And the following params method:
def link_params
params.require(:link).permit(:title)
end
Results in this error:
NoMethodError (undefined method `permit' for "{\"title\":\"My first title\"}":String):
Any ideas what the convention here is to get strong params + json working would be much appreciated.
Update
Here's the code that makes the request (with the http client axios):
axios({
method: 'post',
url: '/api/v1/links.json',
responseType: 'json',
params: {
link: {
title: "My first title"
}
},
})
.then( (response) => {
});
As per the docs here
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
Replace params: with data:.
Related
I have set up a rails api and it only response in the following format which is done through the serializer:
data: { user_name: 'Test User' }
And on the view side, I have got the following partial:
.user-change
= render partial: 'test_user', locals: {user_name: current_user.name}
What would be the correct way to change the user_name as per the API response from the following successful ajax request?
$("#change-me").click(function() {
var user_id;
user_id = $("#user_id").val();
$.ajax({
url: "/api/v1/user/change/" + user_id,
method: "POST",
dataType: "json",
data: JSON.stringify({
{
user_id: user_id,
}
}),
success: function(res, status, xhr) {
let response = res.data;
let userName = response.user_name;
// Update user_name after this event on the partial?
}
},
error: function(res) {
}
});
})
Partial code: _test_user.html.haml
.col-md-9
%p= "Hi! This is the request change from #{user_name}."
In a Rails 5.1 app (without jQuery) how can I pass nested params via a GET ajax request?
I have the following
Rails.ajax({
url: select.getAttribute('data-url') + "?xxx",
type: "GET"
});
If I replace xxx with, for instance, pippo=pluto, in my controller
params[:name] #=> "pluto"
However, in my controller, I need to be able to access a nested param as below.
params[:user][:name] #=> "pluto"
It seems a simple problem but I cannot find a solution.
Here my JS
document.addEventListener('turbolinks:load', function() {
var select = document.querySelector("select[name='user[name]']")
if(select.options[select.selectedIndex].value) {
Rails.ajax({
url: select.getAttribute('data-url'),
type: "GET",
data: {
user: {
name: select.options[select.selectedIndex].value
}
}
});
}
});
Which produces (user[:name] is always selected)
{"object Object"=>nil, "controller"=>"steps", "action"=>"index"} permitted: false>
The query string works fine (but is ugly)
Rails.ajax({
url: select.getAttribute('data-url') + '?user[name]=' + select.options[select.selectedIndex].value,
type: "GET"
});
SIDE QUESTION: To avoid the ajax request in the first place is there an alternative way to automatically trigger the request of the select below when the page is loaded? Currently, it is triggered only when the selected option changes
<%= f.select :user, MyUsers.all,
{ data: { remote: true, url: duplicate_users_path } } %>
use data option in ajax (recommended)
Rails.ajax({
url: select.getAttribute('data-url'),
type: 'GET',
data: {
users: {
pippo: 'pluto',
pippo2: 'pluto2'
}
}
});
or query string as array
Rails.ajax({
url: select.getAttribute('data-url') + '?users[pippo]=pluto&users[pippo2]=pluto2',
type: 'GET'
});
I have followed this tutorial: https://blog.andrewray.me/how-to-set-up-devise-ajax-authentication-with-rails-4-0/ And am using rails 5.1.
I have implemented the json response in the controller:
class RegistrationsController < Devise::RegistrationsController
respond_to :json
end
And when I call the ajax I only get an Html/Text response:
function createUser(callback) {
$.ajax({
type: "POST",
url: window.urls.createUser,
data: {
authenticity_token: $("meta[name=csrf-token]").attr("content"),
user: grabOrderFormUserData()
},
success: function(data) {
console.log("Data: " + data);
},
error: function (data) {
//console.log("error");
}
})
}
That call works fine, but returns the HTML page of the sign up.
The url I use is createUser: hostUrl + '/users/'
What did I miss?
And no, if I add .json to my url, it will respond with 500 error code.
I think you missed to mention dataType: "json" with your ajax call , try this
function createUser(callback) {
$.ajax({
url: window.urls.createUser,
type: "POST",
data: {`enter code here`
authenticity_token: $("meta[name=csrf-token]").attr("content"),
user: grabOrderFormUserData()
},
dataType: "json",
success: function(data) {
console.log("Data: " + data);
},
error: function (data) {
//console.log("error");
}
})
}
and also in your controller try to call this block in case if you are not getting json response,
respond_to do |format|
format.json {
render json: {.....}
}
end
thank you.
In a react-native app, I have the following post request that goes to a rails controller
fetch(POST_PAID_UP, {
method: 'POST',
body: JSON.stringify({
receipt_num: 127,
}).replace(/{|}/gi, "")
})
In the appropriate action of my rails controller I can examine params it looks like this;
{"\"receipt_num\":127"=>nil, "controller"=>"ios/accounts", "action"=>"create"}
so the data is being received. From params I need to extract the value of 'receipt_num'. I have tried JSON.parse(params), but I receive this error;
TypeError: no implicit conversion of Array into String
So how should I parse this data?
You need to add headers that indicate that the information being sent is of type json. So add the following hash to the fetch instruction;
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
You can then remove the .replace(/{|}/gi, "") which is just a work around to overcome the fact that you were not specifying the data was json. The final code should look like this:
fetch(POST_PAID_UP, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
receipt_num: transactionIdentifier,
})
})
You can find more information about fetch here
I have an MVC action that expects an array of int (int[] ids). I'm using $http post of angularjs but everytime I post it would return a null
$http({
method: 'POST',
url: url,
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;' },
data: $.param({
pcode: $scope.pcode,
bId: $scope.bId,
brandIds: [898,55],
regId: $scope.regId,
__RequestVerificationToken: getVerificationToken() // this is Html.Antiforgery that the action needs for posts
})
}).success(function (result) {});
I tried this solution
AngularJs $http.post() does not send data
but it's throwing an injection error if i inject the $httpProvider. I'm using angularjs 1.3
$http({
method: 'POST',
url: url,
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;' },
data: $.param({
pcode: $scope.pcode,
bId: $scope.bId,
brandIds: [898,55],
regId: $scope.regId,
__RequestVerificationToken: getVerificationToken() // this is Html.Antiforgery that the action needs for posts
},true)
}).success(function (result) {});
When you do not supply that parameter it will encode array brandids[]. You can see this in request.form. This is not working with mvc model binding.
If you supply that value then it encode array as brandids. This is what mvc model binder need so it will work.