I am trying to have a function grab an object from a php file on another page. I'm using the jQuery ajax function to to do the json grab, which is working correctly. The issue is when I try to return that object from the function.
The first time I log the object (from within the success function) it is correct in the console, but the returned object from the function getGantt() logs as "undefined".
How do I get this object out of the function?
My code:
function getGantt(requestNumber){
var ganttObject;
$.ajax({
type: "POST",
url: "get_gantt.php",
data: {request_number: requestNumber},
success: function(returnValue){
ganttObject = $.parseJSON(returnValue);
console.log(ganttObject); //this logs a correct object in the console
}
});
return ganttObject;
}
$(function(){ //document ready function
var requestNumber = $('#request_number').text();
var ganttObject = getGantt(requestNumber);
console.log(ganttObject); //this logs "undefined"
}); //end document ready function
The A in Ajax is an important part of the acronym. Asynchronous JavaScript and XML is asynchronous.
$.ajax({success:someFunction}) means Make an HTTP request and when the response arrives, run someFunction
return ganttObject runs before the response arrives.
You should do anything you want to do with the data inside someFunction and not try to return data to the calling function.
The A in AJAX stands for asynchronous. So the call immediately returns and as soon as it finishes, the success callback is called.
So, simply change your code to use a callback:
function getGantt(requestNumber, callback) {
var ganttObject;
$.ajax({
type: "POST",
dataType: 'json',
url: "get_gantt.php",
data: {request_number: requestNumber},
success: function(returnValue){
callback(returnValue);
}
});
}
$(function() {
var requestNumber = $('#request_number').text();
var ganttObject = getGantt(requestNumber, function(ganttObject) {
console.log(ganttObject);
});
});
Btw, I've also removed this parseJSON stuff - setting dataType to json does the job and is less dirty.
I know why it's not returning it at least. The ganttObject may be in the same scope, but the success function is ultimately running in the readyState callback from the XMLHTTP object, so it's on a different thread than the getGantt function. Can you make the $(function(){... code apart of your success function?
Related
On alert it always alerts jojo. The test2.php have text Loco
The div gets updated to Loco but the global variable is not changing. I tried window.temp = data but it didn't worked.
How can i get the returned value in variable? please Guide...
<div>
yolo
</div>
<script type="text/javascript">
var temp = 'jojo';
$.ajax({
url: 'test2.php', //Loco
success: function(data)
{
temp = data;
$('div').html(data);
},
error: function (err)
{
alert('error');
}
});
alert(temp);
var toBeUsedLater = temp; //updated temp value from ajax call
refreshTab();
</script>
This is an asynchronous function. (That's what the A in AJAX stands for.) You are alerting the value of temp immediately , so it is happening before the asynchronous call has finished. If you add
alert(temp);
To the end of your success handler, you will see the value has updated.
AJAX - asynchronous means you are not waiting for response to come and Javascript is interpreted language executed one line after another line. So here the alert(temp) would be executed first and then the success callback as it takes some time to get the response.
1)change
var temp = 'jojo'
to
'temp = 'jojo'
As this is not tied down to the execution context and not limited to files (has pluses and minuses - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
2) The problem is that the alert is called before the callback.
Move the alert into the function. As the ajax is called asynchronously, meaning the success and error functions are called, only when the ajax gets the response back from the server, while the alert you have now will be called right away.
http://javascript.about.com/od/ajax/a/ajaxasyn.htm
$.ajax({
url: 'test2.php', //Loco
success: function(data)
{
temp = data;
$('div').html(data);
alert(temp).
},
error: function (err)
{
alert('error');
}
});
3) alternatively you could set the async of the ajax to false:
What does "async: false" do in jQuery.ajax()?
Which will cause the Ajax call will finish before the next line of code, but it is highly recommended not to do that.
Just add async: false in your ajax options.
I'm experimenting with JQuery and trying to create a function to get dynamic data from a JSON returned API and store it in a global variable (I don't know if this is the right/best way to do this).
What I have so far is
function getdata(url){
var data = $.ajax({
type: 'GET',
url: url
});
return data;
};
So far everything works fine, but this returns an object with a "responseJSON" key and I can't seem to find a way to navigate to this key and then do a $.each loop through the arrays in it.
So the questions are:
Is this the right / way ( if not please explain your answer)
How do you navigate through a multidimensional object containing arrays in the "responseJSON" key.
Another approach is to pass a callback to your function so you can set the response handler within the function and less code when you call your getData method
function getdata(url, callback){
var data = $.ajax({
type: 'GET',
url: url
}).done(callback).error(function(){
alert('Oppps...something went wrong')
});
return data;
};
getData('urlstring', function(data){
/* doSomething with data */
})
AJAX is asynchronous. That means it runs in the background while the rest of your script runs. At a point in the future when the AJAX call completes, then you can access it.
In jQuery, $.ajax returns a promise. So what you can do is the following:
getdata('/path/to/your.json').done(function(data){
// Use your JSON data here
console.log(data);
});
What happens is that once the AJAX call is done, your .done() function will run and you will have access to the data returned.
Don't try to access the properties of the $.ajax object (the responseJSON won't be populated until the call is finished). Use callbacks to get at the returned data.
If you want the json data to be in global scope, just define a global variable (that is, outside the function), and then in the function fill it with the returned data. Something like so:
var api_response;
function get_data(url) {
$.post(url, function(j) { api_response = j; }, "json");
// or
$.getJSON(url, function(j) { api_response = j; });
}
You don't even need to create a function for this and can use jquery's own $.getJSON (the or case).
Sorry if this is a duplicate but I couldn't find any satisfying answers in the previous posts.
$(function() {
$.ajax({
url: 'ajax/test.html',
success: function(data) {
// Data received here
}
});
});
[or]
someFunction() {
return $.ajax({
// Call and receive data
});
}
var myVariable;
someFunction().done(function(data) {
myVariable = data;
// Do stuff with myVariable
});
The above code works just fine. However, this ajax request is made on page load and I want to process this data later on. I know I can include the processing logic inside the callback but I don't want to do that. Assigning the response to a global variable is not working either because of the asynchronous nature of the call.
In both the above ways, the 'data' is confined either to the success callback or the done callback and I want to access it outside of these if possible. This was previously possible with jQuery 'async:false' flag but this is deprecated in jQuery 1.8.
Any suggestions are appreciated. Thank you.
You can "outsource" the callback to a normal function, so you can put it somewhere, you like it:
$(function() {
$.ajax({
url: 'ajax/test.html',
success: yourOwnCallback
});
});
somehwere else you can define your callback
function yourOwnCallback(data) {
// Data received and processed here
}
this is even possible with object methods as well
This solution might not be idea but I hope it helps.
Set the variable upon callback.
Wherever you need to process the data, check if variable is set and if not wait somehow.
Try:
$(document).ready(function(){
var myVar = false;
$.ajax({
url: 'ajax/test.html',
success: function(data) {
myVar=data;
}
});
someFunction(){ //this is invoked when you need processing
while(myVar==false){}
... do some other stuff ..
}
});
Or
someFunction(){
if(myVar==false){
setTimeout(someFunction(),100); //try again in 100ms
return;
}
.. do some other stuff ..
}
I'm sure the solution is staring me right in the eyes, but I just cannot see it. I am trying to load an object from an outside file source. I've tried it several which ways using jQuery's built in methods, but keep returning undefined. Is my issue the scope? I need partnerData right where it is because of other dependent methods in my script. I don't want to operate the rest of my site's functions from within the $.get callback. Any help is greatly appreciated, here's the code:
$(function() {
var partnerData;
$.get('data/partners.json', function(file) {
partnerData = $.parseJSON(file);
});
console.log(partnerData); /* returns undefined instead of object */
});
EDIT:
Thanks for all the feedback everyone. This is the solution I went with:
var partnerData;
$.ajax({
url: 'data/partners.json',
dataType: 'json',
async: false,
success: function(data) {
partnerData = data;
}
});
The reason why you're seeing undefined is because ajax requests are asynchronous by default. This means your get method gets invoked and the code flow moves down to the next statement while the request executes in the background. Your callback function is later invoked when the request completes.
Using callback functions is a common pattern used in situations like this. But you seem to be saying you don't want to do or can't do that. In that case, you could use async: false which would force the request to be synchronous. Keep in mind however, that your code will be blocked on the request and if it's a long-lived request, the user experience will degrade as the browser will lock up.
P.S. You shouldn't need to parseJSON - if response has the correct mime-type set, jQuery will intelligently guess the type and parse the JSON automatically. And in case the server isn't sending back the correct mime-type, you can also explicitly tell jQuery what the expected return data type is; see the dataType argument to $.get() .
One way you might modify your code, to force synchronous requests:
$.ajax({
type: 'GET',
url: 'data/partners.json',
success: function(file){
partnerData = $.parseJSON(file);
//ideally you would perform a callback here
//and keep your requests asynchronous
},
dataType: 'json',
async: false
});
function is proccessed to the end event when ajax is still being proccessed. insert it into callback function
$(function() {
var partnerData;
$.get('data/partners.json', function(file) {
partnerData = $.parseJSON(file);
console.log(partnerData);
});
});
I would say that your problem is the same of the one that I just solved, if $.get is AJAX! and it is setting a variable, to read that variable outside the callback you need to wait the response! So you have to set async=false!
console.log in synchronous and get is async.
try:
$(function() {
var partnerData;
$.get('data/partners.json', function(file) {
partnerData = $.parseJSON(file);
test();
});
function test(){
console.log(partnerData);
}
});
This is probably really stupid but i can't find the problem with my code. It fetches a url that returns json and the function is then supposed to return a string:
function getit() {
var ws_url = 'example.com/test.js';
var user = false;
$.getJSON(ws_url, function(data) {
alert('user '+data.user);//shows john
user = data.user || false;
});
return user;//should return john but returns false
}
test.js will have something like this:
{"id":"12","username":"ses","user":"john","error":""}
or like this:
{"error":"123"}
I also tried if (data.user) {} else {} but it didn't work either..
So what am i missing?
Thanks :)
The problem comes from the fact that the $.getJSON() call is asynchronous. Once the ajax request is fired off, processing continues on inside getit(), and your function immediately returns false. Later on, the Ajax response returns and sets user, but your getit() function returned a long time ago!
You can force the Ajax call to be synchronous using the async option, like this:
$.ajax({
async: false,
url: ws_url,
type: "GET",
success: function(data) {
alert('user '+data.user);//shows john
user = data.user || false;
}
});
If you do that, your browser will block on the script until the Ajax call returns. Generally this isn't the ideal behaviour (which is why the default is async: true), so I'd suggest reworking whatever it is that's calling getit(), and have it expect to process it's results whenever it can, perhaps by passing it's own callback function to getit() that would then be executed when getit() is done.
Ajax is asynchronous, which means that the rest of the script isn't going to sit around and wait for it to finish before moving on. As in your example, the return line is being reached before the ajax function receives a response from the server, thus the user variable is still false at that point in time.
If you want to force an ajax call to run synchronously, you can use jQuerys $.ajax method and set the async parameter to false.
$.ajax({
url:ws_url,
dataType:"json",
async:false,
success:function(data){
alert('user '+data.user);//shows john
user = data.user || false;
}
});