Can't access global variable in jQuery $.get within function - javascript

Below is some code I'm having trouble with. Basically, I'm defining an empty array as a global variable (var playlist = []) and then trying to add elements to it within a jQuery $.get call. From what I've read on the internet, I should be able to do this! The following code gives the error: "Cannot call method 'play' of undefined". playlist[0] does get set within the function, alerting playlist[0] within the $.get call gives the expected result, but it doesn't persist outside the function.
var playlist = [];
function playArtist(artist){
$.get('media/songs/' + artist,
function(data){
for (var i in data){
playlist[i] = setSong(data[i].Resource.name,'track' + data[i].Media.id,i + 1);
}
$('#track-total').text(parseInt(playlist.length));
},'json'
);
playlist[0].play();
}
Can anyone help?
Thanks!

You don't have to do any of this. I ran into the same problem with my project. what you do is make a function call inside the on success callback to reset the global variable. As long as you got asynchronous javascript set to false it will work correctly. Here is my code. Hope it helps.
var exists;
//function to call inside ajax callback
function set_exists(x){
exists = x;
}
$.ajax({
url: "check_entity_name.php",
type: "POST",
async: false, // set to false so order of operations is correct
data: {entity_name : entity},
success: function(data){
if(data == true){
set_exists(true);
}
else{
set_exists(false);
}
}
});
if(exists == true){
return true;
}
else{
return false;
}
Hope this helps you .

Chances are, playlist is getting used before $.get returns - as ajax calls are asynchronous. It works within the success callback because that gets fired once the request has completed, so it will contain the data you expect.

.get is asynchronous, hence the need to provide a callback function. While your get is still in process you are trying to use the array, probably before it's actually been populated.

Related

javascript global variable not updating in ajax callback

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.

How to store $.getJSON object in global variable and navigate through it later

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).

How to check if ajax call exists using jQuery?

I know my title isn't very clear.
For example, this is the structure of my code:
if (foo == something) {
// Ajax call 1, let it be $.ajax("foo1.html") and so on
} else {
// Ajax call 2, let it be $.ajax("foo2.html") and so on
}
How would I test if $.ajax("foo1.html") has actually been run?
Please don't tell me to test if foo == something again. My actual code is much, much more complicated, so please answer the question from the view of the ajax call.
Is this possible at all?
I'm not sure if I understood you right, but jQuery will mix a Deferred object into its jXHR object and you can just check its state.
var resp = $.ajax({});
// somewhere else...
if( resp.state() === 'resolved' ) {
}
Other states are rejected and pending, see http://api.jquery.com/deferred.state/
Of course, you can get all advantages of those Deferred objects aswell, like adding more event handlers for certain things afterwards (.done(), .fail(), etc) or just wait for the promise to fullfil using $.when().
You can set a callback in your ajax call:
$.ajax({
url: "foo1.html"
}).done(function() {
alert('Done!');
});
I would set variable before AJAX call and reset it in the success callback like that :
var isRunning = true;
$.ajax({
url: url,
success: function(resp){
isRunning = false;
}
});
I had similar issues. I used this code:
var isRunning = false; // whether ajax call is running
if(isRunning==false){
isRunning = true;
$.ajax({
// do your stuff
// make sure you set
isRunning = false;
// on success
});
}
Wrap the call in a try catch.
if the call to 'foo1' fails because the method does not exist on the server, in the catch call foo two and then three all the way down until you have exhausted all your fall backs.
If you know the method exists and think it will fail, then set a status on it that can be returned if the server fails then handle the return in the ajax callback.

jQuery function execution order

I am having a problem, or perhaps a lack of understanding, with the jQuery execution order of $.get() function. I want to retrieve some information from a database server to use in the $.ready() function. As you all know, when the get returns, it passes the data to a return handler that does something with the data. In my case I want to assign some values to variables declared inside the ready handler function. But the problem is, the return handler of $.get() does not execute until after ready has exited. I was wondering if (a) am I doing this right/is there a better way or if (b) there was a way around this (that is, force the get return handler to execute immediately or some other fix I'm not aware of). I have a feeling this is some closure thing that I'm not getting about JavaScript.
As per request, I'll post an example of what I mean:
$(function() {
var userID;
$.get(uri, function(returnData) {
var parsedData = JSON.parse(returnData);
userID = parsedData.userID;
});
});
So as you can see, I'm declaring a variable in ready. Then using a get call to the database to retrieve the data needed. Then I parse the JSON that is returned and assign the userID to the variable declared before. I've tested it with a couple alerts. An alert after the get shows userID as undefined but then an alert in get's return handler shows it to be assigned.
$.get() is asynchronous. You have to use a callback to fill your variable and do the computation after the request is complete. Something like:
$(document).ready(function(){
$.get( "yourUrl", function( data, textStatus, jqXHR ) {
var myData = data; // data contains the response content
// perform your processing here...
registerHandlers( myData ); // you can only pass "data" off course...
});
});
// your function to register the handlers as you said you need to.
function registerHandlers( data ) {
// registering handlers...
}
$.get is an ajax request. A in AJAX stand for asynchronous, so script won't wait for this request to finish, but instead will proceed further with your code.
You can either use complete callback or you can use $.ajax and set async to false to perform synchronous request.
The $.get() function executes an async httprequest, so the callback function will be executed whenever this request returns something. You should handle this callback outside of $.ready()
Maybe if you explain exactly what do you want to do, it would be easier to help!
Are you looking for something like:
$(document).ready(function(){
var variable1, variable 2;
$.get('mydata.url', function(data){
variable1 = data.mydata1;
variable2 = data.mydata2;
});
});
If you declare the variables first, then you can set their values within the get call. You can add a function call at the end of the get handler to call a separate function using these values? Without some kind of example, its hard to go into any more detail.
Without seeing the full code, my guess is that you should declare your variable outside $.ready; initialize it in ready for the initial page load; then update it from the get callback handler.
for example
var x = ""; // declaration
$(document).ready(function() { x = "initial value"; });
$.get(...).success(function() { x = "updated from ajax"; });

Variable ends up undefined after using $.get

This seems like an incredibly simple issue but I have no idea why I'm getting undefined. I'm using jQuery to fetch data off a PHP script - specifically a string which the PHP file echoes. Here's the code:
<script type="text/javascript">
var map1;
$.get("script.php", function(data)
{
map1 = data;
});
alert(map1);
</script>
Now if I alert(map1), it ends up being undefined... why exactly is this the case? I thought by declaring map1 outside $.get, it would fix the problem but that's not the case. If I alert(map1) inside the $.get function, it ends up fine and the variable holds a string (as opposed to being undefined). So the question is... what's going on with map1? And how can I stop it from being undefined / going out of scope / whatever is happening to it?
Thanks in advance.
Because your alert is executed before get finished. Put right after assignment in function body. get initiates the request and returns.
As #Michael has put, the .get call is asynchronous so your javascript is executing this call, and then carrying on with your script, which is why you get an undefined alert box.
Your best option is to put in a success call:
$.get("script.php", function(data)
{
map1 = data;
})
.success(function() { alert(map1); });
$.get runs asynchronously, and this is why the function's second parameter is an anonymous function. This anonymous function is invoked once $.get has finished executing. alert(map1) is invoked immediately, and not asynchronously. You could add the alert call to the anonymous function passed to $.get:
$.get("script.php", function(data){
map1 = data;
alert(map1);
});
Because your $.get fills the data slower than your alert is executed !
Which means your $.get function takes longer to compute than your alert !
You could use setTimeout() to work around this but I think its a bad practice.
What about doing it this way?
var map1;
$.ajax({
type: "GET",
url: "script.php",
async: true,
success : function(data)
{
map1 = data;
alert (data);
}
});

Categories