Get data back from ajax call within ajax call - javascript

I'm need some help figuring out how to get back data from the second ajax call, not the first.
I have this method that calls my ajax calls
var projectWithIssues = getProjects().done(function(result) {
....
}
When I look at the results from this, I get back the results on my first ajax call(getEnt_PodType().done()). I want to get the results from the second ajax call within getProjects(). I understand the reason I'm getting the first results back is because I have the return on the first ajax call. However, If I don't have a return there. I get a undefined on the line above. How can I return the data from the second call?
function getEnt_PodType() {
var ent_PodType;
var oDataUrl = //URL to my data;
return $.ajax({
url: oDataUrl,
type: "GET",
async: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("ACCEPT", accept);
},
success: function (xhr, textStatus) {
}
});
}
function getProjects() {
return getEnt_PodType().done(function (res) {
var ent_PodType;
if (res.d.results != undefined) {
ent_PodType = res.d.results[0].Ent_PodType;
}
console.log("The ent pod type value is " + ent_PodType);
var QUERY_FILTER =
"$filter=Ent_PodType eq '" + ent_PodType + "'";
var url = restUrl + QUERY_FILTER;
// I want to return the results from this ajax call
$.ajax({
url: url,
type: "GET",
async: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("ACCEPT", accept);
},
success: function (xhr, textStatus) {
//projects = parseODataResultTest(xhr);
//return projects;
}
});
});
}
Thanks in advance!

Try utilizing pattern found at deferred.then
// first request
var request = $.ajax(url1),
chained = request.then(function( data ) {
console.log(data) // first request response data
// return second request
return $.ajax(url2)
});
chained.then(function( data ) {
console.log(data) // second request response data
// data retrieved from url2 as provided by the first request
});
var request = $.ajax("https://gist.githubusercontent.com/guest271314/23e61e522a14d45a35e1/raw/62775b7420f8df6b3d83244270d26495e40a1e9d/ticker.json"), // first request , `html` document
chained = request.then(function( data ) {
console.log(data) // `["abc"]`
// return `data` from second request
return $.ajax("https://gist.githubusercontent.com/guest271314/6a76aa9d2921350c9d53/raw/49fbc054731540fa68b565e398d3574fde7366e9/abc.txt")
});
chained.then(function( data ) {
console.log(data) // `abc123`
// data retrieved from url2 as provided by the first request
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Use .then instead of .done, it allows better chaining of functions.
Break your code apart so that the two AJAX calls are in separate functions, and have both those functions return the result of their $.ajax call. You can then use:
func1().then(func2).then(...);
func2 will be passed the result of the first AJAX call, and then the result of that will be passed to whatever function is in the final then.
In your case you can also put the call to parseODataResultTest in the chain and then the final function will (eventually) be called with the required data, i.e.:
getEnt_PodType().then(getProjects).then(parseODataResultTest).then(function(projects) {
// use projects here, and _only_ here because it won't
// be in scope or defined anywhere else
...
});

Related

How to create callback function using Ajax?

I am working on the jquery to call a function to get the return value that I want to store for the variable email_number when I refresh on a page.
When I try this:
function get_emailno(emailid, mailfolder) {
$.ajax({
url: 'getemailnumber.php',
type: 'POST',
data : {
emailid: emailid,
mailfolder: mailfolder
},
success: function(data)
{
email_number = data;
}
});
return email_number;
}
I will get the return value as 6 as only when I use alert(email_number) after the email_number = data;, but I am unable to get the value outside of a function.
Here is the full code:
var email_number = '';
// check if page refreshed or reloaded
if (performance.navigation.type == 1) {
var hash = window.location.hash;
var mailfolder = hash.split('/')[0].replace('#', '');
var emailid = 'SUJmaWg4RTFRQkViS1RlUzV3K1NPdz09';
get_emailno(emailid, mailfolder);
}
function get_emailno(emailid, mailfolder) {
$.ajax({
url: 'getemailnumber.php',
type: 'POST',
data : {
emailid: emailid,
mailfolder: mailfolder
},
success: function(data)
{
email_number = data;
}
});
return email_number;
}
However, I have been researching and it stated that I would need to use callback via ajax but I have got no idea how to do this.
I have tried this and I still don't get a return value outside of the get_emailno function.
$.ajax({
url: 'getemailnumber.php',
type: 'POST',
async: true,
data : {
emailid: emailid,
mailfolder: mailfolder
},
success: function(data)
{
email_number = data;
}
});
I am getting frustrated as I am unable to find the solution so I need your help with this. What I am trying to do is I want to call on a get_emailno function to get the return value to store in the email_number variable.
Can you please show me an example how I could use a callback function on ajax to get the return value where I can be able to store the value in the email_number variable?
Thank you.
From the jquery documentation, the $.ajax() method returns a jqXHR object (this reads fully as jquery XMLHttpRequest object).
When you return data from the server in another function like this
function get_emailno(emailid, mailfolder) {
$.ajax({
// ajax settings
});
return email_number;
}
Note that $.ajax ({...}) call is asynchronous. Hence, the code within it doesn't necessarily execute before the last return statement. In other words, the $.ajax () call is deferred to execute at some time in the future, while the return statement executes immediately.
Consequently, jquery specifies that you handle (or respond to) the execution of ajax requests using callbacks and not return statements.
There are two ways you can define callbacks.
1. Define them within the jquery ajax request settings like this:
$.ajax({
// other ajax settings
success: function(data) {},
error: function() {},
complete: function() {},
});
2. Or chain the callbacks to the returned jqXHR object like this:
$.ajax({
// other ajax settings
}).done(function(data) {}).fail(function() {}).always(function() {});
The two methods are equivalent. success: is equivalent to done(), error: is equivalent to fail() and complete: is equivalent to always().
On when it is appropriate to use which function: use success: to handle the case where the returned data is what you expect; use error: if something went wrong during the request and finally use complete: when the request is finished (regardless of whether it was successful or not).
With this knowledge, you can better write your code to catch the data returned from the server at the right time.
var email_number = '';
// check if page refreshed or reloaded
if (performance.navigation.type == 1) {
var hash = window.location.hash;
var mailfolder = hash.split('/')[0].replace('#', '');
var emailid = 'SUJmaWg4RTFRQkViS1RlUzV3K1NPdz09';
get_emailno(emailid, mailfolder);
}
function get_emailno(emailid, mailfolder) {
$.ajax({
url: 'getemailnumber.php',
type: 'POST',
data : {
emailid: emailid,
mailfolder: mailfolder
},
success: function(data)
{
// sufficient to get returned data
email_number = data;
// use email_number here
alert(email_number); // alert it
console.log(email_number); // or log it
$('body').html(email_number); // or append to DOM
}
});
}

AJAX wrapper for jQuery

I want to make a convenience method for my Ajax calls as it is used extensively in the project.
As of now a typical call in the project looks like this.
$.post(
"url",
{
param1: value1,
param2: value2
},
function (data) {}
);
This call is repeated multiple times in the project with different parameters so I would like to be able to create a function to which I can pass the parameters and it will handle the entire Ajax call without me having to write the code every time.
Expected Output:
var data= {firstName:"John", lastName:"Doe", age:46};
do_ajax_request(data);
The function do_ajax_request in turn contains the actual Ajax code which makes the actual request and handles the result.
If possible I would also like for it to return a callback in case I need to perform any extra operations, would a promise work for that?
This would be a global function so I can access it from any JavaScript file.
So many complicated answers for something jQuery supports out of the box. Turning my comment to an answer.
You are basically just coding a wrapper for a wrapper so you do no have to recode some basic lines. No harm in that since it is easy to make the change in one place vs many.
So defined your function and just return the Ajax object that jQuery has. You can than use the done, fail, always methods.
function do_ajax_request (data) {
return $.post("url", data);
}
do_ajax_request({"foo":"bar"})
.done( function(){})
.fail(function(){})
do_ajax_request({"foo":"bar"})
.done( function(){})
.fail(function(){})
If you want to have common code inside, you can do that too, basic idea for an error handler...
function do_ajax_request (data) {
var xhr = $.post("url", data);
xhr.fail(function () {
console.log(arguments)
});
return xhr;
}
I have written several jQuery plug-ins for use in my projects, and have brought along my ajax call method in nearly everyone. Here is a snippet of it from one of my projects. Enjoy!
Method Signature:
obj = An object you want to pass to the ajax call in the data parameter. Pass null if not needed.
method = ajax methods: POST, GET, PUT, DELETE, etc. Default is GET.
endPoint = Url to call.
returnType = html, json, text, etc.
success = callback method when the call is successful.
beforesend = method to call before the send. This is useful when you need to set headers before a call.
failure = callback method when the call is unsuccessul.
var _api = {
call: function (obj, method, endPoint, returnType, success, beforesend, failure) {
obj = obj === null || undefined ? {} : obj;
$.ajax({
method: method || 'GET',
data: !$.isEmptyObject(obj) ? JSON.stringify(obj) : null,
contentType: function () {
switch (returnType) {
case 'json':
return 'application/json';
case 'text':
return 'text/plain';
case 'buffer':
return 'arraybuffer';
case 'html':
default:
return 'text/html';
}
}(returnType === 'json' ? 'application/json; charset=utf-8' : ''),
url: endPoint,
dataType: returnType,
beforeSend: function (xhr, obj) {
if (beforesend) {
beforesend(xhr, obj);
} else {
_api.showLoader();
}
}
}).done(function (data, textStatus, xhr) {
if (success) success(data)
}).fail(function (data, textStatus, xhr) {
if (failure) failure()
}).always(function () {
// Implement code here that you want to run whenever the call is complete regardless of success or failure.
});
}
}
You could create a prototype to with a constructor to handle the input - make the request and handle the response:
ajax.requests = function ( data ) {
this.data = data;
return this.doRequest();
};
ajax.requests.prototype = {
doRequest : function () {
var _this = this;
$.ajax({
data: _this.data
}).done(function(data) {
Handle response and return!
});
}
};
// USAGE
var response = new ajax.requests( yourData );
By returning the $.post, you can use a callback like .done(), chain them together with .then(), etc.
function do_ajax_request(data) {
return $.post( ... ); //RETURN the object
}
var myData = { ... };
do_ajax_request(myData).done(function(result) {
console.log("AJAX complete: " + result);
});
Just another take on this that maybe you hadn't considered. Rather than trying to wrap what is essentially already a wrapper, consider encapsulating your common functionality, like handling errors and dealing with results and using this when executing an ajax request with the existing jQuery ajax wrapper(s)
function handleError(e){
// your common error handling
}
function handleResult(result){
// your common result handling
}
// then every time you execute a request, use your shared functionality
$.post(url, data)
.fail(handleError)
.done(handleResult);
Using code below, you'd need to import config object or declare on top of the functions.
I made two versions for POST and GET respectively
function getJSON(param, absoluteRestUrl = '') {
if (!absoluteRestUrl) {
absoluteRestUrl = config.adminRestEndpoint; // defaultUrl
}
return new Promise(async (resolve, reject) => {
let res = null;
res = await $.getJSON(absoluteRestUrl, param);
resolve(JSON.parse(JSON.stringify(res)));
});
}
function postJSON(param, absoluteRestUrl = '') {
if (!absoluteRestUrl) {
absoluteRestUrl = config.adminRestEndpoint; // defaultUrl
}
return new Promise(async (resolve, reject) => {
let res = null;
res = await $.post(absoluteRestUrl, param, null, 'json');
resolve(JSON.parse(JSON.stringify(res)));
});
}

How call a callback of an Ajax function in another function

I have an Ajax function which is loading data from a webservice. It looks like this:
$.ajax({
type: 'POST',
url: back + this.path_Uri,
data: {msg:this.msg},
dataType: "json",
success: function (data, statut) {
// traitement to not execute here
window.reloadFreelancersMission= data;
var number = reloadFreelancersMission.pagination[0].pagenbr;
window.pagination.ReloadPager(number);
/////////////////////////////////////////////////
},
error: function (data) {
console.log(data);
}
});
I need to do some treatment in the result of the response of this web service in another function in another file.
My file contains a function of sending data within my ajax function. It looks like this
sendFiltres: function () {
$("body").on('change', '.filtres' , function () {
var choix_filtres = $("#fitre_recherche");
var msgJson = JSON.stringify(serializeObject($("#fitre_recherche")));
window.sendData.start(choix_filtres,msgJson);
})
},
So I need here to use the callback of my function in this way:
request.done(function( msg ) {
console.log( msg );
});
and integrate my treatment, to obtain this for:
request.done(function( msg ) {
window.reloadFreelancersMission= data;
var number = reloadFreelancersMission.pagination[0].pagenbr;
window.pagination.ReloadPager(number);
});
but it seems that I can't call this callback in this file. I'm allowed to use it only in the same file of my ajax function, and that's exactly my problem.
In my case, I resolved my problem by recuperating the response of my service within the callback function of jQuery ajaxSuccess
$(document).ajaxSuccess(function (event, xhr, settings) {
if (settings.url === window.find_mission.route.getmission || settings.url === window.find_freelance.route.getfreelance) {
xhr = xhr.responseJSON;
var pagenumber = xhr.pagination[0].pagenbr;
window.pagination.ReloadPager(pagenumber);
}
});
where I was using the xhr variable to get my data.

Set variables in JavaScript once function finishes

I have two functions that makes Ajax calls: getData and getMoreData. getMoreData requires a url variable that is dependent on the url variable getData. This questions continues from: String append from <select> to form new variable.
By appending an item obtained from the received from getData onto a base URL, I create a new variable (Let's call this NewDimensionURL) that I use for getMoreData url. However, NewDimensionURL will show error because the original list (from getData) has yet to be populated and will append nothing onto the base URL.
An idea that I have is to set NewDimensionalURL once getData finishes populating the combobox, so that getMoreData can run after.
JavaScript
var GetDimensions = 'SomeURL1';
//--Combines URL of GetDimensionValues with #dimensionName (the select ID)
var UrlBase = "Required URL of getMoreData";
var getElement = document.getElementById("dimensionName");
var GetDimensionValues = UrlBase + getElement.options[getElement.selectedIndex].text;
function handleResults(responseObj) {
$("#dimensionName").html(responseObj.DimensionListItem.map(function(item) {
return $('<option>').text(item.dimensionDisplayName)[0];
}));
}
function handleMoreResults (responseObj) {
$("#dimensionId").html(responseObj.DimensionValueListItem.map(function(item) {
return $('<option>').text(item.dimensionValueDisplayName)[0];
}));
}
function getData() {
debugger;
jQuery.ajax({
url: GetDimensions,
type: "GET",
dataType: "json",
async: false,
success: function (data) {
object = data;
handleResults(data);
}
});
}
function getMoreData() {
debugger;
jQuery.ajax({
url: GetDimensionValues,
type: "GET",
dataType: "json",
async: false,
success: function (data) {
object = data;
handleMoreResults (data);
}
});
}
Answered
Reordered as:
var GetDimensionValues;
function handleResults(responseObj) {
$("#dimensionName").html(responseObj.DimensionListItem.map(function(item) {
return $('<option>').text(item.dimensionDisplayName)[0];
}));
GetDimensionValues = UrlBase + getElement.options[getElement.selectedIndex].text;
}
Created onchange function Repopulate() for getMoreData() to parse and for handleMoreResults() to populate.
I'm guessing you just do getData(); getMoreData() back to back? If so, then you're running getmoreData BEFORE getData has ever gotten a response back from the server.
You'll have to chain the functions, so that getMoreData only gets executed when getData gets a response. e.g.
$.ajax($url, {
success: function(data) {
getMoreData(); // call this when the original ajax call gets a response.
}
});
Without seeing your code it's hard to say if this is the right solution, but you should try chaining the functions:
$.ajax({url: yourUrl}).then(function (data) {
// deal with the response, do another ajax call here
}).then(function () {
// or do something here
});

Looping through array with callback

I am trying to run through a array send to a php file and on a callback send the next value after the php has completed its download. Here what i have so far.
my array come through as follows.
["http://example.com/test1.zip", "http://example.com/test2.zip", "http://example.com/test3.zip", "http://example.com/test4.zip", "http://example.com/test5.zip"]
above is the output from console.log(values); below. it grabs some urls from checkbox values.
$('.geturls').live('click',function(){
var values = new Array();
$.each($("input[name='downloadQue[]']:checked"), function() {
values.push($(this).val());
ajaxRequest($(this).val(),function(response){
console.log(response);
});
});
console.log(values);
return false;
});
this then calls a ajax function which i am trying to do a callback on.
function ajaxRequest(urlSend,callback){
var send = {
url: urlSend
}
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>index.php/upload",
data: send,
//dataType: "json",
//timeout: 8000,
beforeSend: function() {
},
success: function(response) {
callback('added');
},
error: function (response) {
callback('false');
}
});
}
this will then send to a php file.
function upload(){
$output = shell_exec("wget {$_POST['url']} 2>&1");
return true;
}
What i am trying to do is after the callback from one url which it has download fully then grab the next value from the array and download that url and so on until all the urls in the array are downloaded fully.
at the moment it just downloads the first value and then crashes because it doesn't restart the loop after a return value of true is returned.
Hope this makes sense to someone just looking for some help on the best way to loop through an array of values with a callback after complete.
May be this structure can help you. In this variant you go next URL only after successful completion of the previous Ajax call.
var arr = ['url0','url1','url2','url3'];
var index = 0;
function Run(){
DoAjax(arr[index]);
}
function Next( ){
if(arr.count = index-1)
{
index =0;
return;
}else{
DoAjax(arr[index ]);
}
}
function DoAjax(url){
$.ajax({
type: "POST",
url: url,
data: send,
beforeSend: function() {
},
success: function(response) {
index ++;
Next();
// Addition logic if needed
},
error: function (response) {
}
});
}
Run()
Now that I have a bit more time, I thought it would be good to show an alternative which takes advantage of the fact that jquery ajax is now implemented as a deferred. Meaning you can use pipe chaining to do all the work for you. I've also eliminated the callbacks by taking advantage of the deferred behavior.
This should give you the idea.
// Use jquery deferred pipe chaining to force
// async functions to run sequentially
var dfd = $.Deferred(),
dfdNext = dfd,
x,
values = [],
// The important thing to understand here is that
// you are returning the value of $.ajax to the caller.
// The caller will then get the promise from the deferred.
ajaxRequest = function (urlSend) {
var send = {
url: urlSend
}
return $.ajax({
type: "POST",
url: "<?php echo base_url(); ?>index.php/upload",
data: send,
});
};
// Starts things running. You should be able to put this anywhere
// in the script, including at the end and the code will work the same.
dfd.resolve();
// Deferred pipe chaining. This is the main part of the logic.
// What you want to note here is that a new ajax call will
// not start until the previous
// ajax call is completely finished.
// Also note that we've moved the code that would
// normally be in the callback.
// Finally notice how we are chaining the pipes by
// replacing dfdNext with the return value from the
// current pipe.
for (x = 1; x <= 4; x++) {
values.push(x);
dfdNext = dfdNext.pipe(function () {
var value = values.shift();
return requestAjax(value).
done(function(response) {
// Code here that you would have
// put in your callback.
console.log(response);
}).
fail(function(response) {
console.log(response);
};
});
}
Working example you can play with on jsFiddle.

Categories

Resources