Can someone shed a light on this, so I have multiple GET ajax calls and its only a few lines of codes but I'm basically repeating $.ajax({}) on every function.
Can I have 1 function of $.ajax({}) instead and use this on the functions so I don't need to repeat $.ajax({}) every time?
Something like this maybe but I'm sure its not right but its just a concept.
function ajaxCall(url, method) {
$.ajax({
url: url,
method: method,
success: function(){ } // however this should come in the below function
})
}
function firstCall() {
var url = 'www.urlsample.com';
var methodType = 'GET'
ajaxCall(url, methodType).success() // get the data from this function?
}
Is this somehow possible to do? its to avoid repeating ajax call for every function.
jQuery's .ajax() method returns a Promise-Wrapper.
function ajaxCall(url, method) {
// return promise
return $.ajax({
url: url,
method: method
});
}
function firstCall() {
var url = 'www.urlsample.com';
var methodType = 'GET'
ajaxCall(url, methodType).then(function( result ) {
// success handler
}, function( error ) {
// error handler
});
}
Related
I want to return the second ajaxcall as result of the ajax function, can anyone help me.
private ajax(url: string, method:string, data:any = null) {
var _this = this;
return this.csrfWithoutDone().done(function (res) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': res
}
});
return $.ajax({
url: _this.baseUrl + url,
type: method,
data: data,
});
});
}
the csrfWithoutDone function:
return $.ajax({
url: _this.baseUrl + '/api/csrf',
type: 'GET'
});
BTW: this is writen in typescript but if you replace private with function and remove the : (type) it works in js too.
What you should do is CHAIN the calls.
The .done() function is asynchronous. Therefore it will execute whatever you pass it as an argument when the response is back. That function's returned value goes nowhere.
What you should do instead is:
foo.then(function() { /*step 1 /}).then(function({ / step 2 */ })
I would suggest reading a little bit about asynchrounousity in Javascript.
This is the way you would do it with promises, I have never worked with jQuery so the syntax might differ.
edit: I would add that there is no way to return the response value in your initial function. the best you can do is return the jqXHR object, And then call the "then()" or "done()" from the caller.
You should return a Promised object in your ajax function, to be able to find out if your request is done or not. Since you are using jQuery, you can use Deferred Objects:
function ajax(url, method, data) {
var _this = this;
// Create a deferred object
var dfd = $.Deferred();
this.csrfWithoutDone().done(function (res) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': res
}
});
$.ajax({
url: _this.baseUrl + url,
type: method,
data: data,
}).done(function (response) {
// your inner ajax has been done
// tell your promised object and pass the response to it
dfd.resolve(response);
});
});
// return promised
return dfd.promise();
}
// call your ajax function, it is a promised object
var ajaxRequest = ajax();
// so you can wait for the response
ajaxRequest.done(function (response) {
// your ajax has been done and you have the response
console.log(response);
});
I've implemented a simple code to find out how Promised object works:
function ajax() {
var dfd = $.Deferred();
setTimeout(function () {
dfd.resolve('Hello World');
}, 1000);
return dfd.promise();
}
var testResult = ajax();
testResult.done(function (response) {
alert(response);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can use native Promise Object as well, and maybe you need polyfill, to support all browsers, see Can I Use.
I'm trying to do a little web in JavaScript + Ajax and I want to do it recursively. I've never used ajax before and the problem is I don't know to finish functions. The code looks like that:
var cont = 0;
var function1 = function (query) {
$.ajax({
url: '...',
data: {
.
.
.
},
success: function (response) {
instructions;
function2(param1, param2);
}
});
};
var function2 = function (query, param2) {
$.ajax({
url: '...',
data: {
.
.
.
},
success: function (response) {
instructions;
function3(param1, param2, param3);
}
});
};
var function3 = function (query, param2, param3) {
if (cont == 2) {
console.log("finish");
return;
}
var test = $.ajax({
url: '...',
data: {
.
.
.
},
success: function (response) {
if (...) {
cont++;
instructions;
var audio = new Audio(...);
audio.play();
audio.onended = function () {
instructions;
function3(query, param2, param3);
return;
};
} else {
instructions;
function3(query, param2, param3);
};
return;
}
});
return;
};
document.getElementById('search-form').addEventListener('submit', function (e) {
e.preventDefault();
function1(document.getElementById('query').value);
}, false);
So basically, when cont == 2I try to get out of javascript function3 with return; but some part of the program ( I don't know if the success: function (response) or the full javascript function3 ) is still running and instructions are being executed.
How could I solve this?
First off, the way to do this properly is to make use of jQuery's deferred objects.
As you have probably noticed, the program doesn't simply wait at the ajax request, and then proceed to the 'success' handler. This is because Javascript uses a non-blocking/waiting model. So you call $.ajax({params,...}), this sends the request, but whatever's after this will then immediately run, without waiting. Then, once the top level function has finished executing and nothing else is running, the response can be processed, and the 'success' handler is invoked.
So how to do this stuff properly? Start by arranging your request functions like this:
function doRequest1() {
return $.ajax({
url: '...',
data: {
.
.
.
}
});
}
function doRequest2(parameter) {
return $.ajax({
url: '...',
data: {
.
p: parameter
.
}
});
}
Notice that we aren't providing a success handler, but we are returning the value that $.ajax returns. This is a deferred object which is used to represent a request which has been sent, but for which a response hasn't been received/handled. You can attach a handler to the object like this:
var r1 = doRequest1();
r1.then(function() {
// Do stuff on success...
});
A nice thing about these objects is that they can be chained using 'then'.
'then' accepts a function which takes the value of the old request and produces a new request to do next:
var allRequests = doRequest1().then(function(result1) {
return doRequest2("hello");
});
The 'allRequests' variable is now a deferred object representing the result of doRequest2. How do you get this result? You use 'then()', just like any other deferred:
allRequests.then(function(result) {
alert("All requests completed. Result of last one: " + result);
});
Make sure that you understand how the result from 1 request can be used to set the parameters for the next one, or even decide which request to make next.
If you don't need one request's result to determine the next, rather, you just want to run a number of requests and wait for them all to complete, you can use a shortcut, 'when':
$.when(doRequest1(),doRequest2(), doRequest3()).then(function(result1,result2,result3) {
// All done
});
Another nice thing about deferreds is that they can be cancelled:
allRequests.abort();
Using the above, hopefully you can see how to restructure your code so you get a sequence of requests with a function to run after all 3 have completed.
Watch the value of your global variable cont through the flow of your program. It may be that it is (never) equal to 2 when function3() is called and that is why your program continues.
Method for handling ajax
function ajaxMethod(){
return $.ajax({
url: ajaxUrl,
type: "POST",
dataType: "JSONP",
jsonpCallback: ajaxCallback
});
}
Calls to this method:
dD(ajaxMethod());
aA(ajaxMethod());
bB(ajaxMethod());
cC(ajaxMethod());
aa,bb,cc,dd method have
promise.success(function (response) {
console.log(response);
});
Now aA response is coming in bB function,,bb response in cc function and as simultaneous call is coming.
Also tried using async true nothing happens.
Any suggestions?
With jsonpCallback you are telling jQuery to use a specific function name for the callback function (instead of generating a unique one), so each time you call it, you overwrite the previous function.
Just remove jsonpCallback: ajaxCallback.
While you are at it, remove type: "POST",, it is incompatible with JSONP.
I think this is what you are after.
This code is using the returned promise to wait for the result then passing the result to your other function.
ajaxMethod().success(function(response)
{
dD(response);
});
ajaxMethod().success(function(response)
{
aA(response);
});
ajaxMethod().success(function(response)
{
cC(response);
});
ajaxMethod().success(function(response)
{
dD(response);
});
Your aA, bB, cC and dD methods can now be:
function <insertname>(response)
{
console.log(response);
}
If you want your request to come in the synchronous way, then try the following :
var callBack = $.Callbacks();
callBack.add(dD(ajaxMethod()));
callBack.add(aA(ajaxMethod()));
callBack.add(bB(ajaxMethod()));
callBack.add(cC(ajaxMethod()));
callBack.fire();
the above line of code will make sure the respective ajax call would get call.
I have a jquery function like this:
function get()
{
$.ajax({
url: 'get.php',
success: function(data) {
$('#get').html(data);
$('#get').fadeIn(2000);
setTimeout(posts,2000);
}
});
}
get();
I want to stop this function when i click on a certain element in a webpage, how would i do this.
Thanks
Set a variable for your AJAX request.
var getajax;
function get() {
getajax = $.ajax({
......
});
}
When you want to abort it, simply
getajax.abort();
In a situation where you may not be able to globaly define all of your .ajax() call variables (as shown by another answer by #uzyn), this might be a suitable solution.
You could simply wrap your success callback with a flag indicating whether you want to cancel the result.
var ajax_canceled = false;
function get(){
$.ajax({
url: 'get.php',
success: function(data) {
if (!ajax_canceled){
//...
}
}
});
}
get();
$("#cancel_ajax").on('click',function(){
ajax_canceled = true;
});
I've got into a small trouble here. In my document.ready function I've defined an object and that object is being populated by three different ajax calls(inside document.ready). Now I want to do a
console.log(myObject);
only when the 3 async calls have been executed completely. Please suggest a way to do this.
Using I would suggest you to create a function like this:
function onAllInformationIsReady() {
console.log(myObject);
}
function isAllInformationReady() {
// verify here if you have all the information
}
and you do something like this on your ajax calls (I'm not assuming you are using jQuery here, replace with your ajax call method)
$.ajax({
type: "POST",
url: "some.php",
data: "...n",
success: function(msg){
if(isAllInformationReady())
onAllInformationIsReady();
}
});
By the way, if you are using jQuery you can make synchronous ajax calls like this:
$.ajax({
type: "POST",
url: "some.php",
data: "...n",
async: false,
success: function(msg){
}
});
Try jQuery 1.5's new "deferred" objects:
var j1 = $.ajax(...);
var j2 = $.ajax(...);
var j3 = $.ajax(...);
j1.success(function(data) {
// do something with data
});
j2.success(function(data) {
// do something with data
});
j3.success(function(data) {
// do something with data
});
$.when(j1, j2, j3).done(function() {
console.log(myObject);
});
The three .success() functions will be called asynchronously and will populate myObject, and then the done function will only be invoked by $.when() once all three AJAX requests have been completed.