$.ajaxSetup global data doesnt merge in load function - javascript

I would like to set a global data parameter for all my ajax requests
$.ajaxSetup({
data: {hash : "12345"}
});
after setting this I call:
var myData = {
name : "John",
age : "28"
}
$.get(url, myData, function(data){
...
});
this works fine and add all 3 parameters (hash, name, age) to request data
but when I call load function instead of get, it doesnt work and I get only 2 parameters (name, age):
$("#my_div").load(url, myData, function(data){
...
});
please could anyone tell me why it doesnt work for load function? I have many usages of load function in my app and I dont want to change load on get
thank you for every tip!

This could be considered a bug in jQuery; or at the very least, they should accept the interface between their AJAX methods are inconsistent.
The only way to fix this is by using jQuery.extend to merge the default data with the data you've provided:
jQuery.extend(myData, jQuery.ajaxSettings);
Before making the request.
How its a bug:
load converts the data object into a string before passing in onto the underlying jQuery.ajax method, where as get doesn't.
Because of this, when ajaxExtend builds the data object, in the load scenario the data parameter is set to the string, whereas with get the data object is merged with jQuery.ajaxSettings.

If you take a look at .load, you'll see it does not pass an object to .ajax, even if you pass one to .load:
if ( params ) {
...
} else if ( typeof params === "object" ) {
// it will execute this
params = jQuery.param( params, jQuery.ajaxSettings.traditional );
It will call jQuery.params, which returns a string, and the object cannot be merged with the string. So it will send "name=John&age=28" without combining the hash object.
This is not the case for $.get, because that function directly passes the object:
jQuery.each( [ "get", "post" ], function( i, method ) {
jQuery[ method ] = function( url, data, callback, type ) {
...
return jQuery.ajax({
type: method,
url: url,
data: data, // passed directly to $.ajax which takes care of merging $.ajaxSetup stuff
success: callback,
dataType: type
});
};
});

Related

In Javascript array there are items, but when I pass an array to an MVC Controller, list/array is empty

I'm using ajax POST method
to send objects stored in an array to Mvc Controller to save them to a database, but list in my controller is allways empty
while in Javascript there are items in an array.
here is my code with Console.Log.
My controller is called a ProductController, ActionMethod is called Print, so I written:
"Product/Print"
Console.Log showed this:
So there are 3 items!
var print = function () {
console.log(productList);
$.ajax({
type: "POST",
url: "Product/Print",
traditional: true,
data: { productList: JSON.stringify(productList) }
});}
And when Method in my controller is called list is empty as image shows:
Obliviously something is wrong, and I don't know what, I'm trying to figure it out but It's kinda hard, because I thought everything is allright,
I'm new to javascript so probably this is not best approach?
Thanks guys
Cheers
When sending complex data over ajax, you need to send the json stringified version of the js object while specifying the contentType as "application/json". With the Content-Type header, the model binder will be able to read the data from the right place (in this case, the request body) and map to your parameter.
Also you do not need to specify the parameter name in your data(which will create a json string like productList=yourArraySuff and model binder won't be able to deserialize that to your parameter type). Just send the stringified version of your array.
This should work
var productList = [{ code: 'abc' }, { code: 'def' }];
var url = "Product/Print";
$.ajax({
type: "POST",
url: url,
contentType:"application/json",
data: JSON.stringify(productList)
}).done(function(res) {
console.log('result from the call ',res);
}).fail(function(x, a, e) {
alert(e);
});
If your js code is inside the razor view, you can also leverage the Url.Action helper method to generate the correct relative url to the action method.
var url = "#Url.Action("Print","Product)";

jQuery: Add sub-object to a "data" object on every ajax request on the page

Is it possible to extend jQuery.ajax method so it will add some static sub-data object to jQuery.ajax.data on any/every ajax request?
For example, if one of my ajax requests is:
jQuery.ajax({
url: 'request_file.php',
data: {
data1: $("#dataField1").val(),
data2: $("#dataField2").val(),
data3: $("#dataField3").val()
},
// ...
success: function (result)
{
// ...
},
// ...
});
I also want "data4: window.someGlobalVar" to be automatically added in this and in any other ajax requests on the page without implicitly writing it inside every data object?
Thanks.
You can use ajaxSetup. Do this once:
$.ajaxSetup({data: { "data4": window.someGlobalVar }});
Then, any subsequent $.ajax call, like the one you wrote, will include this data value.
You could use jQuery's ajaxPrefilter
It is a filter that will be executed right before executing every ajax. There you get the options passed to the $.ajax method, and you could extend the new property, like this:
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
originalOptions.data.data4 = $("#dataField4").val()
});

Why is jQuery.ajax() Calling my Objects Functions?

I'm having an issue where jQuery.ajax() is calling my data objects functions. For example, I have an object structure similar to the following:
var TestFactory = (function () {
var _id;
var _attributes;
return {
createObject: function (objectId) {
var value = null;
_id = objectId;
_attributes = {};
function _showErrorStatus() {
$('label')
.css('background-color', 'red')
.css('color', 'black')
.text('jQuery called me...');
}
function _attr(key, value) {
if (value == null) {
return _attributes[key];
}
_attributes[key] = value;
return this;
}
return {
id: _id,
attributes: _attributes,
showErrorStatus: _showErrorStatus,
attr: _attr,
}
}
}
})();
I'd like to use this object as the data value for my jQuery.ajax() call, as follows:
var myObject = TestFactory.createObject(12345);
myObject.attr('name', 'Fred Flinstone');
$.ajax({
url: '/echo/json/',
type: 'GET',
data: myObject,
dataType: 'json',
});
The issue I'm running into is jQuery.ajax() is calling the showErrorStatus() function from the object returned by the factory --nowhere in my code do I call this function.
I like the OOP qualities I get out of using this object, so is there any way to handle this case without a significant rewrite (e.g., dropping all my functionality from the "class")?
NOTE: I found it difficult to explain this problem, so here is a complete running example on jsfiddle.
Use JSON.stringify (not a jQuery method).
$.ajax({
url: '/echo/json/',
type: 'GET',
data: JSON.stringify(myObject),
dataType: 'json',
});
http://jsfiddle.net/HJ9AS/10/
It happens because it's a feature, though not documented as far as I can tell.
If you pass an object, then it assumes you want it to call any functions that are values of object properties.
One way of doing it is to use a function like Underscore's pick(). It can be used to cherry-pick certain properties you need from the object. It is a useful library anyways, but you can also implement this simple method if you wish.
$.ajax({
url: '/echo/json/',
type: 'GET',
/* only send id and attributes! */
data: _.pick(myObject, 'id', 'attributes'),
dataType: 'json',
});
It might be a nice habit to always whitelist stuff, not just send everything blindly. Specifying exactly what to send can save you from future surprises (like the one you just encountered). Most of the time you simply don't want to send everything that is stored in your object.
You can also implement some way for your object to be able to return its sendable contens. It could get a .getJSON() method that just collects from the object everything to be sent.
Concerning the function calling:
Processing the data property uses $.param(), which has this in the docs:
As of jQuery 1.3, the return value of a function is used instead of the function as a String.
This is a feature, not a bug :). I understand the logic behind it, because if there is a function in the object that you just specified as data to be sent, there must be a good reason behind it...
Instead of passing data: myObject,
try setting this: var serializedObject = myObject.param()
then passing data: serializedObject
Check out jQuery's param function here.

How to process JSON output in AJAX?

I have this code snippet in .js file
$(function () {
// KeyDates
var url = "http://localhost:8732/Design_Time_Addresses/Intel.IIP.MDF.WCF/ProgramCalendarService/GetKeyDatesCalendarNew";
$.ajax({
url: url,
data: null,
type: 'POST',
contentType: 'application/json',
dataType: 'json',
success: function (GetKeyDatesCalendarDataNew) {
alert(GetKeyDatesCalendarDataNew);
$(document).ajaxStop($.unblockUI);
}
});
});
How do i process the key value pair in GetKeyDatesCalendarDataNew?
You probably want to know how to access an object's props. For that, use the for in loop to iterate over the object's values:
success: function (GetKeyDatesCalendarDataNew) {
for(var key in GetKeyDatesCalendarDataNew)
{
var value = GetKeyDatesCalendarDataNew[key];
// do somehitng based on the key and/or value iterated
}
}
For this case, the argument of the success function is the evaluated JSON that was returned from the Ajax request. Therefore GetKeyDatesCalendarDataNew, which you should rename to something like data, becomes the actual data that your server returned.
You can only process the data if you know its structure. One simple way of knowing this would be to do console.log(GetKeyDatesCalendarDataNew) and then easily process it with a for loop if it's an array or for x in.. if it's an object.
You can use JQuery "getJSON" function where you need to pass the url and specify a callback function.Your ajax call will be handled by the getJSON function. In the callback function, you can access the Keys as properties. A nice example
Lav G
$.each(GetKeyDatesCalendarDataNew,function(key,value){
//do something here
})

jQuery $.post - how to call a callback function if $.post fails and or if the response is not the type you expect

Here's the thing, I have a jquery click event handler, that calls a post on click.
The type that it expects (4th parameter of $.post()) is "json". However, on the
server side; there are two responses to the post: it's either json or html response. The problem is, if it returns html, the callback function isn't called (because the $.post expects a json?).
How can I react to this? I want something that if the server side script returns a json, execute callback, otherwise do another. Is that possible? Can I check the response type with $.post?
You'll most likely want to use the generic jquery.ajax function. In particular the dataType: 'text' property should allow you to parse your return value in whatever method works for you. You can also use the parseJSON function
$.ajax({
url: 'url',
type: 'post'
dataType: 'text',
success: function(text) {
if (json) {
var obj = $.parseJSON(text);
} else {
var html = $(text);
}
}
});

Categories

Resources