Not able to pass parameters through url in Ajax request using Rails - javascript

I'm trying to pass a parameter through a url in an Ajax request that's triggered by a confirmation dialogue. I'd like to fetch the value of that parameter in my Rails controller given a successful request but I haven't been able to do it.
I've tried so far the following code:
Here my Ajax request where I've been adding the param in the URL plus other params in data
function continueSave() {
var name = $('#leader_name').val();
var persisted_time = $('#leader_time').val();
$.ajax({
type: "POST",
url: "/leaderboards/1/?test=1",
data: { leader: { name: name, time: time } },
success: success
});
}
Here the dialogue-related JS
function nameAlert() {
return confirm("Name already exists. Would you like to continue?");
};
(function() {
if (nameAlert()) {
continueSave();
}
else {
//something else here
}
})();
Although the request successfully reaches the controller there's params[:test] is nil in the controller.
I've also tried to pass the test param in data, but it is not working either.
Would appreciate some help.
The relevant controller action (leaders_controller.rb)
def create
#leader = Leader.new(leader_params)
#leader.leaderboard_id = #leaderboard.id
#name_repeated = !#leaderboard.leaders.find_by(name: #leader.name).nil?
#check = params[:test]
if params[:test].nil? && #name_repeated == true
render :template => 'leaders/repeated_name.js.erb'
else
#leader.save
#rank = #leader.rank_in(#leaderboard)
respond_to do |format|
if #leader.save
format.html { redirect_to root_path }
format.js { }
else
end
end
end
end
Note:
1.- 'leaders/repeated_name.js.erb' contains the code for the Ajax request
2.- In routes Leader resource is nested within Leaderboard resource

Sorry guys I found the mistake. It was a dumb one.
I have shallow nested routes so that leaders is nested in leaderboards, therefore I was using the incorrect path for the request. It should be:
$.ajax({
type: "POST",
url: "/leaderboards/1/leaders?test=1",
data: { leader: { name: name, time: time } },
success: success
});
I should have caught that before sorry for wasting your time.

I'll post here - my comments are getting too long.
Try adding { type: 1} to your data and changing type to GET. Rails params contain both GET and POST data - you don't even have to change your controller.
function continueSave() {
var name = $('#leader_name').val();
var persisted_time = $('#leader_time').val();
$.ajax({
type: "GET",
url: "/leaderboards/1/",
data: { leader: { name: name, time: time }, test: 1 },
success: success
});
}

Related

MVC Action receives wrong parameter via Jquery AJAX request

I am trying to be familiar with ASP MVC by working on simple MVC project.
But there is a problem I can't figure out.
On certain event, AJAX request is sent to one action taking IDictionary type parameter.
But the received parameter contains controller name, action name and language instead of data specified in Jquery AJAX call.
Please take a look at below code.
RouterConfig
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Language",
url: "{lang}/{controller}/{action}/{id}",
defaults: new {controller = "Login", action="Index", id=UrlParameter.Optional},
constraints: new {lang = #"en|fr"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional, lang = "en" }
);
}
Action
public ActionResult ApproveUsers(IDictionary<string, string> CheckedUsers)
{
return View();
}
JQuery
$('#confirmModal #action').click(function () {
var cb = {};
var data = {};
$("input:checkbox:checked").each(function () {
var key = $(this).attr('value');
var val = $(this).closest('tr').next().find('table').attr('id');
cb[key] = val;
});
$.ajax({
type: "POST",
url: '/AdminHome/ApproveUsers',
dataType: "html",
contentType: 'application/json',
data : JSON.stringify(cb),
success: function (result) {
alert("success");
},
error: function(result) {
alert("failed");
}
});
});
So when button is clicked all the checked checkbox data are sent to ApproveUsers action as keyvaluepair.
But no matter what the cb object in Jquery contains, the IDictionary parameter in ApproveUsers action only is like below
[0] {[ contoller, AdminHome ]}
[1] {[ action, ApproveUsers ]}
[2] {[ lang, en]}
This seems like there is something wrong with RouteConfig. But I don't know why.
I would really appreciate if anyone can help me know why and fix this issue.
Thanks,
I found what's wrong with my code.
I was missing the parameter name in AJAX call so parameter biding failed.
As Steve said, code should be like below.
data : JSON.stringify(CheckedUsers:cb)

Two requests in one time immediatly. ASP MVC + JQuery Ajax

MVC application (ASP.NET MVC, client: jquery).
Problem: The second ajax-request wait, when the first ajax request will done.
I need, when the first and the second ajax-requests executes immediatly in one time.
The page sends to server to determine the count of records (the first ajax-request), very long (~5-7 seconds).
The operator click the buttom to open the card to edit it (the second ajax-request, fast, get the Dto-model).
The user doesn't need to wait the first request, he wants to work immediatly.
As a result, in Chrome in network page, two requests in status 'pending'. The second waits the first.
Question, how can I send requests, to execute asynchronously ?
The first ajax-request:
`window.jQuery`.ajax({
type: 'POST',
url: Url.Action("GetCountBooks", "Book");
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: JSON.stringify({ typeBook: "...", filter: "..." };),
success: function (data) {
// show in UI page the count of books by filter and params
},
error: function (data) {
//show error
}});
public class BookController : Controller
{
[HttpPost]
public NJsonResult GetCountBooks(string typeBook, Filter filter)
{
var data = DbProvider.GetCountBooks(typeBook, filter)
if (data.Result == ResultType.Success)
{
var count = data.Data;
return new NJsonResult
{
Data = new { Data = count }
};
}
return new NJsonResult
{
Data = new { Error = "Error while counting the books." }
};
}
}
The second ajax-request:
`window.jQuery`.ajax({
type: 'POST',
dataType: 'json',
contentType: "application/json",
url: Url.Action("GetBookById", "Book"),
data: JSON.stringify({ id: bookId }),
success: function (data) {
// show jquery dialog form to edit dto-model.
},
error: function (data) {
//show error
}});
public class BookController : Controller
{
[HttpPost]
public NJsonResult GetBookById(int id)
{
var data = DbProvider.GetBookById(id)
if (data.Result == ResultType.Success)
{
var book = data.Data;
return new NJsonResult
{
Data = new { Data = book }
};
return new NJsonResult
{
Data = new { Error = "The book is not found." }
};
}
return new NJsonResult
{
Data = new { Error = "Error while getting the book." }
};
}
}
I Cannot union ajax requests into one! The user can send various second request.
You need a fork-join splitter to fork 2 tasks and join based on some condition.
For example here is my implementation:
function fork(promises) {
return {
join: (callback) => {
let numOfTasks = promises.length;
let forkId = Math.ceil(Math.random() * 1000);
fork_join_map[forkId] = {
expected: numOfTasks,
current: 0
};
promises.forEach((p) => {
p.then((data) => {
fork_join_map[forkId].current++;
if (fork_join_map[forkId].expected === fork_join_map[forkId].current) {
if (callback) callback(data)
}
})
});
}
}}
Pass any number of async tasks (promises) into fork method and join when all are done. The done criteria here is managed by simple global object fork_join_map which tracks the results of your fork-join process (global is not good but its just an example). The particular fork-join is identified by forkId which is 0..1000 in this example which is not quite good again, but I hope you got the idea.
With jQuery you can create promise with $.when( $.ajax(..your ajax call) )
In the end you can join your promises like this
fork([
$.when( $.ajax(..your ajax call 1) ),
$.when( $.ajax(..your ajax call 2) )
]).join(() => {
// do your logic here when both calls are done
});
It's my own implementation, there may be already-written library functions for this in jQuery - I dont know. Hope this will give you a right direction at least.
The solution is to add attribute to Asp Controller: [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/

Jquery ajax POST inconsistent with Hapijs server inject

Here is what my Ajax post looks like:
$.ajax({
type: "POST",
url: "/create",
data: {
"question": $('#question').val(),
"options": options
},
success: function() { window.location.href="/view"; }
});
Fairly simple. options is an array of string charachters. The problem is, when I receive on the server end with Hapijs, the request payload shows this object received:
{
question: "..etc..",
"options[]": [..etc...]
}
Why does it add a [] to the options variable name? Normally this wouldn't be a problem for me, but when I do the same thing and simulate a server request in my lab test like this:
var test = [..etc..]
// Simulate POST request
var serverOptions = {
method: 'POST',
url: '/create',
payload: {
question: 'Question',
options: test
}
};
It shows that the variable name received is just "options", not "options[]". How can I get jquery to stop adding the [] to the variable name when POSTing? Thanks

How to remove header from AJAX call for a single request?

I'm building an app, using Rails and Backbone as my back-end, that requires users to login to access certain pages. On one of the user authenticated pages, I have it setup so they can create an entry in my database, by entering in data, which is then sent to the Google Maps API to retrieve the latitude and longitude.
Via a helper function, I'm checking if the user is authenticated or not, but when I send up the AJAX call to Google Maps API, the user token is also being sent up. Here's the code that I have set up right now.
In my api js file, which is ran first on load for my page
var token = $('#api-token').val();
$.ajaxSetup({
headers:{
"accept": "application/json",
"token": token
}
});
In my users_controller.rb
def profile
authorize!
#user = current_user
#bathrooms = Bathroom.all.sort_by { |name| name }
render layout: 'profile_layout'
end
def authorize!
redirect_to '/login' unless current_user
end
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
Here's my AJAX call
function getInfo(location) {
console.log('getInfo');
$.ajax({
method: 'get',
url: 'https://maps.googleapis.com/maps/api/geocode/json',
data:{address: location, key: 'API KEY GOES HERE'},
success: function(data) {
extractData(data);
}
})
}
You can try following steps:
function getInfo(location) {
console.log('getInfo');
delete $.ajaxSettings.headers["token"]; // Remove header before call
$.ajax({
method: 'get',
url: 'https://maps.googleapis.com/maps/api/geocode/json',
data:{address: location, key: 'API KEY GOES HERE'},
success: function(data) {
extractData(data);
}
});
$.ajaxSettings.headers["token"] = token; // Add it back immediately
}

JavaScript AJAX & Rails Controller (back-and-forth)

I'm sending information back-and-forth between a Rails controller and a JS file.
I'm sending the form to the controller through JS (works)
$("#help-email-submit").ajaxSubmit({url: '/help/send_help_email', type: 'post' });
I'm able to catch the event in the controller (works)
def send_help_email
....
end
In the same JS file that sent the above request, how do I capture the JSON response (below)? (doesn't work)
def send_help_email
...
cst_str = #current_support_ticket.to_s
respond_to do |format|
format.json { render :json => cst_str }
end
end
In the JS file
var xmlhttp = new XMLHttpRequest();
alert(xmlhttp.responseText);
UPDATE
I noticed a JS error that is preventing the success: function from executing:
Error
TypeError: 'undefined' is not a function (evaluating '$("#help-email- form").ajaxSubmit({url: '/help/send_help_email', type: 'post', complete: handlerResponse })')
This is the line that is triggering the error
$("#help-email-form").ajaxSubmit({url: '/help/send_help_email', type: 'post', complete: handlerResponse })
This is complete block
var handlerResponse = function(data) {
alert(data);
};
$('#help-email-submit').live('click', function(e) {
$('#sender-email-wrapper').fadeOut('fast', function() {
$("#help-email-sent").fadeIn('slow');
});
$("#help-email-form").ajaxSubmit({url: '/help/send_help_email', type: 'post', complete: handlerResponse })
e.preventDefault();
});
According to ajaxSubmit documentation, it accepts the same options that the jQuery.ajax method. So, to get the response, you can pass the complete callback to the call:
var handleResponse = function(data) {
// Use response here
};
$("#help-email-submit").ajaxSubmit({url: '/help/send_help_email', type: 'post', complete: handleResponse });
Depending on the version of jQuery that you are using, you can also pass the callback through the complete method on the return value from jQuery.ajax:
$("#help-email-submit").ajaxSubmit({url: '/help/send_help_email', type: 'post'}).complete(function(data) {
// Use response here
});

Categories

Resources