This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I recover data from a Requette in ajax. I want to use this data in a function and return it but when I call the function it returns nothing
function getdata(nom_produit) {
$.ajax({
type: "POST",
url: "traitement/panne/test_panne.php",
data: {
nom_produit: nom_produit
},
success: function(data) {
var obj = jQuery.parseJSON(data);
jQuery.each(obj["resultat"], function(index, value) {
})
}
});
return obj;
}
how i can return the data?
you can't return from like this. $.ajax is an asynchronous call so when return is called your success function is still pending execution. you can do something like below though to achieve same result.
function getdata(nom_produit, callback) {
$.ajax({
type: "POST",
url: "traitement/panne/test_panne.php",
data: {
nom_produit: nom_produit
},
success: callback
});
}
and from the place you are calling this function you can do something like below
var successFunction = function(data) {
hideOverlay(); // hide overlay once response is there
// your code to process data and show in UI
}
showOverlay(); // code to show loading image in UI till response comes
getData(someId, successFunction);
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
Here is my code:
function ajaxRequest(value, path, website){
window[website] = $.ajax({
url : path,
type : 'GET',
data: { "name": value,
"_token": $('meta[name="_token"]').attr('content')
},
beforeSend: function(){
if(window[website] != null) {
window[website].abort();
}
},
success: function (people) {
return [status, people];
},
error: function (jqXHR, textStatus, errorThrown) {
return [status, textStatus];
},
timeout: 15000
});
}
As you see, it's a function that sends ajax requests. I call it like this:
var res = ajaxRequest('Jack', 'search/twitter', 'twitter');
console.log(res);
It returns:
Why I don't see the result in the console? Noted that I can see the result in the console if I send that ajax out of function. (the result is an array of data)
How can I fix the problem?
function ajaxRequest(value, path, website){
return new Promise(function (resolve, reject) {
window[website] = $.ajax({
url : path,
type : 'GET',
data: { "name": value,
"_token": $('meta[name="_token"]').attr('content')
},
beforeSend: function(){
if(window[website] != null) {
window[website].abort();
}
},
success: function (people) {
resolve([status, people]);
},
error: function (jqXHR, textStatus, errorThrown) {
reject([status, textStatus]);
},
timeout: 15000
});
});
}
then do this, to get the result:
ajaxRequest('Jack', 'search/twitter', 'twitter').then(function(res) { console.log(res)}, function(err){console.log(err)})`;
For first you haven't return anything from your function, default is undefined.
Second, your res will not be the result of your ajax call. Because ajax is an asynchronous call, the result which will you get is accessible only in the function success or error.
See here. You can't return this. All other logic which you need to implement based on the data you need to write here.
success: function (people) {
// Your logic here
},
This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 7 years ago.
I call a function which registers a registrationId is issued using chrome.gcm. Everything is fine but because the callback takes time, my code does not work without a console.log or alert. Any tips how I can make it wait?
var registrationId = ""
function register() {
var senderId = 'MY_SENDER_ID';
chrome.gcm.register([senderId], registerCallback);
}
function registerCallback(regId) {
registrationId = regId;
if (chrome.runtime.lastError) {
return false;
}
chrome.storage.local.set({registered: true});
}
$(function(){
$("#register-form").submit(function(e) {
//Disable from further calls
$('#submit').disabled = true;
register()
var name = $('#name').val()
var email = $('#email').val()
//Insert console.log or alert here to slow it down
var chromeId = registrationId
$.ajax({
type: "POST",
url: 'MY_URL',
ajax:false,
data: {chromeId: chromeId, name: name, email:email},
success: function(result)
{
console.log(result)
}
});
});
})
You need to execute the method as part of the callback, since the value that needs to be passed in as part of your AJAX request, is available only after ASYNC process completes.
You can use a Deferred objects in such cases. As soon as the it is resolved you can execute your AJAX call.
$(function() {
$("#register-form").submit(function(e) {
//Disable from further calls
$('#submit').disabled = true;
var senderId = 'MY_SENDER_ID';
// Store the promise in a variable
var complete = chrome.gcm.register([senderId]);
// When resolved it will, hit the callback
// where you have access to the value
// which is then passed to your AJAX request
$.when(complete).done(function(regId) {
var registrationId = regId;
if (chrome.runtime.lastError) {
return false;
}
chrome.storage.local.set({
registered: true
});
$.ajax({
type: "POST",
url: 'MY_URL',
ajax: false,
data: {
chromeId: registrationId,
name: name,
email: email
},
success: function(result) {
console.log(result)
}
});
});
});
});
The code that comes after register() should go in a new callback which accepts registrationId as a parameter, and is passed to register(). Then, register() can call this callback with the registrationId it gets back from chrome.gcm.register. No need for the global registrationId variable.
function register(callback) {
var senderId = 'MY_SENDER_ID';
chrome.gcm.register([senderId], function (regId) {
if (chrome.runtime.lastError) {
return false;
}
chrome.storage.local.set({registered: true});
callback(regId);
});
}
$(function(){
$("#register-form").submit(function(e) {
//Disable from further calls
$('#submit').disabled = true;
register(function (registrationId) {
var name = $('#name').val()
var email = $('#email').val()
//Insert console.log or alert here to slow it down
var chromeId = registrationId
$.ajax({
type: "POST",
url: 'MY_URL',
ajax:false,
data: {chromeId: chromeId, name: name, email:email},
success: function(result)
{
console.log(result)
}
});
});
});
})
Promises and async/await helps with stuff like this, also.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I want to build a javascript class which I initialize and will make only one ajax request to save some data off so I can do stuff with it aftewards. It is important that there is only one request for performance reasons.
Here is the initialisation
var web = new webService();
web.connect(app.info);
web.info();
and this is my class
function webService() {
this.d = new Object;
this.connect = function(app) {
console.log(app);
$.ajax({
url: 'my working url which gives me my jsonp object',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function(data) {
this.d = data;
},
async: false
});
}
this.info = function() {
console.log(this.d);
}
}
I was wondering if there might be a problem with synchronizing? I'm not sure so I wanted to ask you guys.
jQuery $.ajax (and similar methods, like $.getJSON()) will return a Deferred object. Like other JavaScript objects, this is a "thing" which you can store in a variable and pass around in your code. Then you can add (async) callbacks to it at any time:
// Don't include a 'success' callback yet.
$def = $.ajax(...);
// $def is an object which you can store globally
// or pass as an argument into other functions.
//
// Somewhere else, add a success callback:
$def.done(function(data) {
// ...
});
See http://api.jquery.com/category/deferred-object/
If you refactor your code to return a deferred object thus:
function webService() {
this.d = new Object;
this.connect = function(app) {
console.log(app);
return $.ajax({
url: 'my working url which gives me my jsonp object',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function(data) {
this.d = data;
}
});
}
this.info = function() {
console.log(this.d);
}
}
You can then use done:
var web = new webService();
web.connect(app.info).done(function() {web.info();});
this also means your A jax is asynchronous, like it should be.
You could argue if your going down this route though, what is your function webservice even doing. Why not just let deferred do all the work?
this.connect = function(app) {
console.log(app);
var that = this; //store this into a variable
$.ajax({
url: 'my working url which gives me my jsonp object',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function(data) {
that.d = data; //use that so you have the right scope
},
async: false
});
}
other option is to use bind or jQuery's proxy
I have the following function:
loadMsgBody: function (id) {
return dojo.xhrGet({
url: "myurl",
handleAs: "text",
content: {
id: id
},
load: function (response) {
return response;
},
error: function (response) {
alert(response);
}
});
}
And calling it:
var text = "";
this.loadMsgBody(this.msgId).then(function (response) {
text = response;
});
Now I expect to get the return value of the function but instead I am getting an empty value for text. However, in Firebug I do see the response from the server with the correct value. I've searched and found these links : DOJO xhrGet how to use returned json object?
and:
Using hitch / deferred with an xhrGet request
But I still can't get and store the data with the above code. I don't want to do the manipulation inside the xhrGet call, I want to retrieve the data and use as it will be used multiple times.
Is there anything I am missing?
Dojo's XHR methods return instances of the class dojo/Deferred, because they are asynchronous. What this means is that the functions returns before the value of the response is available. In order to work with the results of the asynchronous response you need to wait for it to return. Dojo exposes this using a uniform API, Deferreds. Instances of the dojo/Deferred class have a method then. The then method takes a function as a parameter. That function will execute once the Deferred have been resolved (in this case, when the request has completed).
var deferred = loadMsgBody();
deferred.then(function(response){
//work with response
});
I would try changing your load function to evoke your callback function:
loadMsgBody: function (id, callback) {
return dojo.xhrGet({
url: "myurl",
handleAs: "text",
content: {
id: id
},
load: function (response) {
if(callback) {
callback(response);
}
},
error: function (response) {
alert(response);
}
});
}
Try this:
loadMsgBody: function (id, callback) {
return dojo.xhrGet({
url: "myurl",
handleAs: "text",
content: {
id: id
},
load: function (response) {
callback.apply(null,[response]);
},
error: function (response) {
alert(response);
}
});
}
Then:
var text = "";
this.loadMsgBody(this.msgId, function (response) {
text = response;
console.log("text:",text); // this will show your return data
});
console.log("text:",text); // this will show empty data because ajax call is asynchrize, at this time , data not return yet.
setTimeout(function(){
console.log("text:",text); // this will show your return data again because ajax call should have finished after 30000 ms
},30000)
How do you write a function that returns a value fetched from server via $.get?
This is what I have tried, which does not work:
function getMessage(key) {
$.get("/messages.json", function(data) {
return data.messages[key];
}, "json");
}
Any ideas?
Because Ajax requests are asynchronous. That is why you have to pass a callback to $.get, to handle the data once it is available. But the getMessage function returns before the $.get callback is executed.
You have to pass a callback that is doing something with the return value. E.g.:
function getMessage(key, cb) {
$.get("/messages.json", function(data) {
cb(data.messages[key]);
}, "json");
}
getMessage('foo', function(data) {
alert(data);
});
Of course you can also pass the callack directly to $.get and handle the data extraction there:
function getMessage(cb) {
$.get("/messages.json", cb);
}
There are two ways to handle this: use a synchronmous call via $.ajax or pass in a callback to your function instead of having it return a value. The latter is the canonical way to deal with AJAX since it retains the asynchronous nature of the call.
Asynchronous
function processMessage(key,elem,cb) {
$.get('/messages.json', function(data) {
if (cb && typeof(cb) === 'function') {
cb.apply(elem,data.messages[key]);
}
}
}
$('.something').each( function() {
processMessage('somekey', this, function(msg) {
$(this).append(msg);
});
});
Synchronous - try not to do it this way, since you'll lock your browser until it's done.
function getMessage(key)
{
var result = '';
$.ajax({
url: '/messages.json',
aSync: false,
type: 'get',
dataType: 'json',
success: function(data) {
result = data.messages[key];
}
});
return result;
}
$('.something').each( function() {
var msg = getMessage('somekey');
$(this).append(msg);
});
Note: these are untested.