Passing nested parameters to an ajax get request - ruby-on-rails

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'
});

Related

Rails 6: AJAX data not reaching controller

I'm trying to make a pretty standard ajax call, this is my code:
// app/javascripts/packs/contacts.js
jQuery(() => {
$(".upload-contacts-button").on("click", (e) => {
e.preventDefault();
//...
$.ajax({
url: "/pre-parse-contacts",
type: "post",
data: { my_param: random_param },
success() {},
});
});
});
This is my route:
post 'pre-parse-contacts', to: 'contacts#pre_parse_contacts', as: 'pre_parse_contacts'
For some reason the data I send in the ajax request never reaches the controller, when I try to puts params in the controller action I get this result:
------- DEBUG --------
{"controller"=>"contacts", "action"=>"pre_parse_contacts"}
I'm sure the ajax call is made, even the js.erb view tries to render but I get errors due to I need the data I send in the ajax call. Why is this happening?
Sorry I found the answer to my issue, it seems I was trying to send an array of strings in the params of the ajax request, this is why it was never reaching the controller.
joining the array made the trick:
$.ajax({
url: "/pre-parse-contacts",
type: "post",
data: { my_param: random_param.join() },
success() {},
});

How to send params from nested forms?

I'm making a POST request from a nested form which is written in reactjs such that it is making an ajax request to create method of the products controller.
React Code:
I have an empty object in the getInitialState like this
getInitialState: function() {
return {
products: [{name: '', price: '', quantity: ''}],
count: 1
};
},
When i submit the form,
handleSubmit: function(e) {
e.preventDefault();
var productsArray = this.state.products;
$.ajax({
data: {
product: productsArray
},
url: '',
type: "POST",
dataType: "json",
success: function ( data ) {
console.log(data);
// this.setState({ comments: data });
}.bind(this)
});
},
the object gets populated and the parameter hash becomes like this
Parameters: {"product"=>{"0"=>{"name"=>"", "price"=>"", "quantity"=>""}}, "shop_id"=>"gulshop"}
So i'm getting
ActiveRecord::UnknownAttributeError (unknown attribute '0' for Product.):
How can i get the parameter hash like this:
Parameters: {"product"=>[{"name"=>"", "price"=>"", "quantity"=>""}], "shop_id"=>"gulshop"}
What can be done for it ?
Your original error 'unknown attribute '0' for Product.' is because the Product class does not have an attribute '0'. I'm not sure where the '0' is coming from as you haven't posted your react code that makes the request.
You can easily make a request from your component using jQuery's .ajax method. e.g
$.ajax({
type: 'POST',
url: '/your_url',
data: {
course: {
name: 'Hello World',
price: 120
}
}
});
You would then have something like the following in your controller..
class ProductController < ApplicationController
def create
#product = Product.create(product_params)
end
private
def product_params
params.require(:product).permit(:name, :price)
end
end

Url pathname issue in Ajax Post

In development I make an Ajax post which works in development. However when I put it on the Test server it doesn't work because IIS has assigned the application a subfolder, and this is missing in my development environment.
I have found work around (see below) but I am the first to admit this should not be the solution, as I have to remember to call a function for the url everytime I make an Ajax call.
There must be a better way.
However the code will show you what I am fixing;
function OperationsManagerFlagClickFunc(userId) {
$.ajax({
url: GetUrl("/Users/UpdateOperationsManagerFlag"),
type: "POST",
data: { "userId": userId },
success: function (data) { }
});
}
function GetUrl(path) {
var pathArray = window.location.pathname.split('/');
if (pathArray[1] === "ITOC")
return "/ITOC" + path;
else
return path;
}
If you have your javascript in .aspx file, you can generate url like this:
function OperationsManagerFlagClickFunc(userId) {
$.ajax({
url: "<%= Url.Action("UpdateOperationsManagerFlag","User") %>",
type: "POST",
data: { "userId": userId },
success: function (data) { }
});
}
Why not have a variable defined separately, like siteUrl, that will hold your site's url, with different values on the 2 servers?
Then just do:
url: siteUrl + "/Users/UpdateOperationsManagerFlag"

Rails is not accepting arrays in AJAX calls?

My junk:
jQuery 1.3.2
Rails 2.3.5
If I perform a simple AJAX call like this :
$.ajax({
type: "POST",
url: "/admin/emails/" + id + "/distributions",
dataType: "script",
data: { value: ['1', '2'] }
});
Only 2 will return, not 1 and 2 .
Inside the HTTP POST headers in Firebug, it does say that is sending both :
authenticity_token bMmx0pnJ6ePq6ogwSCR1JH55U7wtrMEOy6ME4rNRmCI=
authenticity_token bMmx0pnJ6ePq6ogwSCR1JH55U7wtrMEOy6ME4rNRmCI=
value 1
value 2
Source
value=1&value=2&authenticity_token=bMmx0pnJ6ePq6ogwSCR1JH55U7wtrMEOy6ME4rNRmCI%3D&authenticity_token=bMmx0pnJ6ePq6ogwSCR1JH55U7wtrMEOy6ME4rNRmCI%3D
But when it hits my debugger in my create method :
{"authenticity_token"=>"bMmx0pnJ6ePq6ogwSCR1JH55U7wtrMEOy6ME4rNRmCI=",
"action"=>"create",
"value"=>"2",
"controller"=>"admin/distributions",
"email_id"=>"3"}
What might be going on here?
UPDATE
If I do this :
$.ajax({
type: "POST",
url: "/admin/emails/" + id + "/distributions",
dataType: "script",
data: { value: ["1",[data.value]], type: data.type }
});
I can get all the zips to pass through..
You should use such data format for this request
data: { value[0]: '1', value[1]: '2'}
this code make correct hash
var c = ['1', '2'];
var i = 0;
var b = {}; //hash for data:
c.each(function(zz){
b["value[" + i +"]"] = zz;
i=i+1;
});
usage:
data: b

jQuery: why does $.post does a GET instead of a POST

I'm trying to do an ajax call and populate the "Data" div with the results of the ajax call,
but i get an error saying: "Server Error in '/' Application. The resource cannot be found. Description: HTTP 404. Requested URL: /Home/GetStuff"
When I look with Firebug the request was a GET to /Home/GetStuff and the answer was 404 Not found. Why I doesn't do a POST as I required in the ajax call? How can I do a POST?
I tried using $.post and got the same behavior, though I haven't checked the jquery code, I assume $.post is a wrapper around $.ajax.
Also i tried Ajax.ActionLink and it works fine, though I would like to use jQuery and not the Microsoft's ajax js libraries.
The code follows:
Home/TestStuff.aspx
function aClick() {
$.ajax({
type: "POST",
url: $("#MeFwd").href,
data: ({ accesscode: 102, fname: "JOHN", page: 0 }),
dataType: "html",
success: renderData
});
};
function renderData(data) {
$("#Data").html(data.get_data());
}
<div id="Data">
</div>
<div id="link">
Click Me!
</div>
HomeController.cs
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetStuff(int accessCode, string fName, int? page)
{
return "<table><tr><td>Hello World!</td></tr></table>";
}
Change your onclick="aClick" to onclick="aClick(); return false;". Clicking the link is doing a get to the url instead of running your JS.
$('#MeFwd').click(function() {
$.ajax({
type: "POST",
url: $("#MeFwd").href,
data: ({ accesscode: 102, fname: "JOHN", page: 0 }),
dataType: "html",
success: function(data){
$("#Data").html(data);
});
});
};
I don't think you can call a function on your return ... but I could be wrong.
Or look into load:
http://docs.jquery.com/Ajax/load#urldatacallback

Resources