I need to synchronously call a controller (url) in my Javascript. I could do this with an Ajax function like so:
$.ajax({
type: 'POST',
url: BASE + '/publication/storeWorldCat',
data: data,
success: success,
dataType: dataType,
async:false
});
I don't understand why I should use an Ajax function with a async:false parameter as Ajax is asynchronous by definition. $post() is asynchronous too.
Is there a better way?
Thanks for your help!
Looking at the documentation of jQuery.ajax (quoting) :
By default, all requests are sent
asynchronously (i.e. this is set to
true by default). If you need
synchronous requests, set this option
to false.
Granted, AJAX stands for Asynchronous Javascript and XML so any request sent in Javascript that is not sent asynchronously or does not use XML as the data format should technically not be called an AJAX request. With the popularity of JSON nowadays, it looks like the $.ajax function is REALLY badly named since it allows any data format.
But many other acronyms are chosen to be easy to pronounce at the cost of not being totally correct, and I think we can live with it. So to answer your questions:
Why has the jQuery team decided to name this function ajax? Because this acronym was already used by everyone, regardless of the data format used and the "synchronousness". Why is everyone using this acronym wrongly? Probably because it did not make sense to make a new acronym for each data format, each time with an optional 'A' for whether it is asynchronous.
Why [you] should use an Ajax function with a async:false parameter as Ajax is asynchronous by definition?
Well, you don't have to:
$.sendRequest = $.ajax
And now you can use a function with a better name in your code. You can even change the default behaviour:
$.sendRequest = function(options) {
if (typeof options.async === undefined) {
options.async = false;
}
$.ajax.apply($, arguments);
}
Related
I'm making a site with several calls to PHP via AJAX, right now AJAX uses POST to get a echoed string from PHP and then compares that in a switch and then does what is required. Example in the code below
function submitPHP(dataForPHP){
//Runs ajax request
$.ajax({
type : "POST",
url : 'initPHP.php',
dataType : 'text',
data : dataForPHP,
success : function(data){
//Checks echoed data from PHP
switch(data){
case "LOGIN_ACCEPTED":
loggedInFunction();
break;
case "LOGIN_FAILED":
loggedInFailedFunction();
break;
}
}
});
}
I'm thinking if there is a way for the PHP to return what function (like "loggedInFunction();") I want to call instead of a string that I then have to compare and then call the function? I can change the AJAX to use JSON instead if that does it.
I've been looking around on other similar questions here on stack on most of them want to echo a whole function which is not what I want to do.
Thanks in advance!
I'd do this.
use HTTPS to perform login, HTTP really is insecure nowadays;
create a controller object with all allowed methods (actions);
call an action of that controller.
The idea of having a controller is convenient on several levels:
security: if a method is not in the controller you cannot call it, so it is a way to know what can be called and what is absolutely not possible to call;
cohesion: the methods are all next to each other and easier to maintain;
encapsulation: if there is any state it can be held easily inside the context of that object.
This is an example:
loginController = {
"acceptAction": function () {
},
"failAction": function () {
}
};
You can now call those methods from the AJAX handler. Say the server tells you what you must do. A verb so to speak, such as accept or fail. You can then do:
"success": function (data) {
loginController[data + "Action"]();
}
And that's it.
BTW: this is just the very basic MVC pattern. Oldie but goldie :)
While learning through ajax in jQuery, I came across 2 terms, viz., $.ajaxPrefilter() and $.ajaxSetup(). All I can find out is that these make some changes in AJAX before loading or making call to $.ajax().
Can someone simplify and explain these terms in easiest form along with a slight comparison of the two?
$.ajaxSetup() - Set default values for future Ajax requests. You could, for example, set the ajax URL that you always want to use for every request here.
Example:
$.ajaxSetup({
// Always use this URL for every request
url: "http://example.com/ajax.php"
});
$.ajaxPrefilter() - Modify existing options before each request is sent. You could, for example, append a query string component to every ajax request that is sent out.
Example:
$.ajaxPrefilter( function(options) {
// Always add "?debug=1" to every URL
options.url += (options.url.indexOf("?") < 0 ? : "?" : "&") + "debug=1";
});
$.ajaxSetup simply takes an options object, and uses it as the defaults for future $.ajax() calls (and other calls that are shortcuts for this, like $.get). For instance,
$.ajaxSetup( { dataType: 'json' });
makes this the default dataType for future calls.
$.ajaxPrefilter lets you run a custom function before sending each AJAX request to the server. It can examine the options to that call, and then change them in any way that it wants. So it provides much more flexibility and control than $.ajaxSetup.
I'm building an SPA using Sammy and Knockout powered by a REST Web Service available on a different URL.
I'm noticing some odd behavior when returning JSONP versus JSON when using $.when().done()...
.done() never fires, but .fail() will, even though the status code I receive is 200, and JSONP Linter tells me that my JSONP is valid:
(function($) {
$(function() {
$.when($.getJSON('endpoint1?callback=?', null),
$,getJSON('endpoint2?callback=?', null))
.done(function(resp1, resp2) {
console.log(resp1); // this is never called
});
})
.fail(function(obj) {
console.log(obj); // this is called, but why?
});
});
})(jQuery);
A sample response returned is:
callback({
"external-links": [
{
"nav_link_text": "Stack Overflow",
"url": "http://stackoverflow.com"
}
]
});
If I return JSON instead of JSONP, .done() works as expected. What am I doing wrong or need to change?
The problem is specified here:
ReferenceError: callback is not defined
Your JSONP response has callback hard-coded. That's incorrect. JSONP needs to set the function name dynamically.
When jQuery sends a JSONP request, it creates a function called jQuery123456 (or something like that) and sends that name in the request. It calls endpoint1?callback=jQuery123456. The job of JSONP is to make a call to that function. Your JSONP needs to return:
jQuery123456({
your: 'data'
})
You need to use the value of the callback parameter.
If for some reason, creating the JSONP "dynamically" isn't an option, you can force jQuery to name the callback function it creates. You need to use $.ajax for this:
$.ajax({
url: 'endpoint1',
dataType: 'jsonp',
jsonp: false, // Don't add the "?callback=?" param,
// you're not using it anyway
jsonpCallback: 'callback' // Force jQuery to use "callback"
// as the function name
});
Note: jQuery probably won't like having the same callback value for multiple requests.
If I wish to fetch data from a remote server, then JSONP is the tool of choice I believe. But I am confused by an example I have seen:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
dataType: 'jsonp',
data: 'p3=c',
jsonp: 'callback',
url: 'http://someserver.com/app?p1=a&p2=b',
success: function (data) {
console.log("data="+data);
$.each(data, function (i, r) {
console.log("i="+i);
console.log("r="+r);
});
},
});
});
</script>
I can see that in the request, a callback parameter has been added with value in the format jQuery1234567890. When I look at the app that processes that request, it extracts the callback parameter from the request and wraps the json data to be returned with that and relevant brackets, so it ends up returning something like this:
jQuery1234567890([{"x":"100","y":"101"},{"x":"200","y":"201"}])
So my first questions are:
(1) Is the app correct to have done what it has?
(2) What has jQuery / JSONP actually done for us?
I was assuming that jQuery would see the dataType of "jsonp", insert a script tag into the DOM, the browser would then download and execute the script. If that's right, has jQuery created the function jQuery1234567890, the implementation of which is to pass the parameter on to the success function?
(3) Is my understanding correct (I don't think it is)?
Thank you,
Paul
(1) Is the app correct to have done what it has?
Yes, that's a correct JSONP format
(2) What has jQuery / JSONP actually done for us?
Notified the server application that JSONP is desired by placing a &callback=jQuery1234567890 in the request
I was assuming that jQuery would see the dataType of "jsonp", insert a script tag into the DOM, the browser would then download and execute the script. If that's right, has jQuery created the function jQuery1234567890, the implementation of which is to pass the parameter on to the success function?
(3) Is my understanding correct (I don't think it is)?
Yes, your understanding is correct. It has created a script with a jQuery1234567890 function which is invoked when the requested scripted is loaded. And as you stated the parameter receives the data and passes it on to the $.ajax internals, which invokes the success callback
From the ajax docs for the jsonp option:
Override the callback function name in a jsonp
request. This value will be used instead of 'callback' in the
'callback=?' part of the query string in the url. So
{jsonp:'onJSONPLoad'} would result in 'onJSONPLoad=?' passed to the
server.
So using jsonp: 'callback' overrides callback with callback, essentially doing nothing.
The other stuff you're seeing is generated by jQuery so that you don't have to do it yourself. You get to simply treat this request like any other ajax request in jquery and not worry about the implementation of the jsonp.
Does anyone know what is the difference between $("#id").load and $.ajax?
Let me clarify things for you a little bit :
$.ajax() is the basic and low-level ajax function jQuery provides which means you can do what ever you want to like you can work with XmlHttpRequest object. But once upon a time jQuery Developers thought that actually besides $.ajax(), they could provide more specific methods to developers so they wouldn't need to pass more parameters to make $.ajax() method work the way they want. For example they said instead of passing json as a parameter to $.ajax() to indicate return data type, they provided $.getJSON() so we would all know that the return type we expected was json, or instead of indicating send method as post or get, you could use $.post() or $.get() respectively.
So load() is the same thing, it can help you inject html data into your html. with load() method you know that an html portion is being expected.
Isn't that cool ?
I think I've been fallen in love.
For more information, you can visit jquery.com, they are even providing their new library and api tutorial page.
Edit :
$.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston",
success: function(msg){
alert( "Data Saved: " + msg );
}
});
is the same as below :
$.post("some.php", { name: "John", time: "2pm" },
function(data){
alert("Data Loaded: " + data);
});
Now as you can see it is the simplified version of $.ajax(), to make post call, you need to pass some information of send method type which is post as shown at the first example but instead of doing this you can use $.post() because you know what you are doing is post so this version is more simplified and easy to work on.
But don't forget something. Except for load(), all other ajax methods return XHR (XmlHttpRequest instance) so you can treat them as if you were working with XmlHttpRequest, actually you are working with it tho :) and but load() returns jQuery which means :
$("#objectID").load("test.php", { 'choices[]': ["Jon", "Susan"] } );
in the example above, you can easly inject the return html into #objectID element. Isn't it cool ? If it wasn't returning jQuery, you should have been working with callback function where you probably get the result out of like data object and inject it manually into the html element you want. So it would be hassle but with $.load() method, it is really simplified in jQuery.
$("#feeds").load("feeds.php", {limit: 25}, function(){
alert("The last 25 entries in the feed have been loaded");
});
You can even post parameters, so according to those parameters you can do some work at server-side and send html portion back to the client and your cute jQuery code takes it and inject it into #feeds html element in the example right above.
load() initiates an Ajax request to retrieve HTML that, when returned, is set to the given selector.
All the jQuery Ajax functions are simply wrappers for $.ajax() so:
$("#id").load(...);
is probably equivalent to:
$.ajax({
url: "...",
dataType: "html",
success: function(data) {
$("#id").html(data);
}
});
A more concise summary and the most important difference is that $.ajax allows you to set content-type and datatype.
These two are important for making JSON requests, or XML requests. ASP.NET is more fussy with a missing content-type field (atleast when you use [WebMethod]) and will simply return the HTML of the page instead of JSON.
$.load() is intended to simply return straight HTML. $.ajax also gives you
caching
error handling
filtering of data
password
plus others.
From the documentation ...
$(selector).load(..)
Load HTML from a remote file and inject it into the DOM.
$.ajax(...)
Load a remote page using an HTTP request. This is jQuery's low-level AJAX implementation.
load is specifically for fetching (via GET unless parameters are provided, then POST is used) an HTML page and directly inserting it into the selected nodes (those selected by the $(selector) portion of $(selector).load(...).
$.ajax(...) is a more general method that allows you to make GET and POST requests, and does nothing specific with the response.
I encourage you to read the documentation.
Here's the source code for the load function: http://github.com/jquery/jquery/blob/master/src/ajax.js#L15
As you can see, it's a $ajax with some options handling. In other words, a convenience method.
The above answer may not be valid anymore in light of the use of deferred and promise objects. I believe that with .ajax you can use .when but you cannot do so with .load. In short, I believe that .ajax is more powerful than .load. For example:
some_promise = $.ajax({....});
.when(some_promise).done(function(){.... });
You get more granular control over the html loading. There is also .fail and .always for failure and "no matter what" cases. You don't get this in load. Hope I am correct on this.