JavaScript scopes with jQuery AJAX [closed] - javascript

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a situation where I want to have a global variable like a whose value I'll be fetching from jQuery Ajax from some server and then want the value to be available on call from other function. To visualize:
var a = [];
$(document).ready(function () {
$.ajax({
type: 'GET',
url: 'some url',
success: function (response) {
a = response.somearray;
},
error: function () {
alert("Not successfull");
}
});
});
function something() { // this function will be called onclick of a button in html
console.log(a); // here I want the value that came from the server. But currently, it's printing empty array
}
What I have tried are as follow:
Removing var keyword from (a) to make it global.
Assigning no value (here empty array) to (a) declaration above (that turned out to be a blunderous mistake though).
Removing (a) declaration completely from the top.
The thing to take care about is that something() function is being called from an HTML button on complete page load and after ajax call. So value is already available.

Here is a working example of what you want, check the console logs:
https://codepen.io/antoniandre/pen/NebpQj?editors=0010
var a = [];
$(document).ready(function () {
$.getJSON("https://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?", {
tags: "snowboarding",
tagmode: "any",
format: "json"
})
.done(function (response) {
a = response.items;
// something(); Don't need this.
});
});
function something() { // this function will be called onclick of a button in html
console.log(a); // here I want the value that came from the server. But currently, it's printing empty array
}
EDIT:
HTML:
<button onclick="something()">hello</button>

Scope was lost, since ajax callback is asynchronous function. I think, it should be
var a = [];
$(document).ready(function () {
var me = this;
$.ajax({
type: 'GET',
url: 'some url',
success: function (response) {
me.a = response.somearray;
},
error: function () {
alert("Not successfull");
});
});

Related

access class function inside ajax success [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 7 years ago.
im trying to assign a variable inside the ajax success callback.
i know that in order to assign the value i need to use a call back function. but i want that function to be inside the class. is it possible to implement something like this?
function callMgmt_class() {
this.room_id = 'Error';
this.assignRoomVar = function(room_id) {
alert();
this.room_id = room_id;
}
this.getRoomID = function() {
$.ajax({
url: "/get_room_id.php",
dataType: "json",
success: function(data) {
this.assignRoomVar(data.room_id);
}
})
}
}
is there some way to use bind?
i tried:
success: function(data) {
(function() { this.assignRoomVar(data.room_id); }).bind(this);
}
so i dont get any errors but the function does not seem to be called.
Your use of this is flawed. 'this' inside the callback will use the context of the callback whereas what you need is the context of your class. You can do that by caching the 'this' context in a variable and using it instead.
this.getRoomID = function() {
var me = this;
$.ajax({
url: "/get_room_id.php",
dataType: "json",
success: function(data) {
me.assignRoomVar(data.room_id);
}
})
}
this is not the this you are looking for.
The this keyword is tricky and takes on different references depending on the context. When you are accessing this in the ajax success function, it is not referring to the callMgmt_class object anymore (I think it would reference the ajax function).
The best way to get around this is to assign this to another variable when you are sure of its value. So at the beggining of your function is the best bet
this.getRoomID = function() {
var that= this;
//Now use that instead of this when you want to refer to the callMgmt_class object
$.ajax({
url: "/get_room_id.php",
dataType: "json",
success: function(data) {
that.assignRoomVar(data.room_id);
}
})
}
Addition:
I think using bind or apply are other alternatives, but I am not very familiar, so I'll leave that for someone else to answer.

Return data from an AJAX request [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I have json data in file that I want to read. It prints to the console.log the correct file data.
How do I get that data into variable x? When I run the code, x is undefined.
function getData() {
$.get('data/APPFeaturesMetaData.json', function (data) {
console.log(data);
return data;
});
};
var x = getData();
It's an asynchronous call, So the var x = getData(); runs before the AJAX request is complete.
The answer is, use deferred it looks something like this:
var request = $.ajax(
{
url: url,
});
// When the request is done, do something with data.
request.done(function (data) {
console.log(data);
});
In your case, it's different if you want to return data, you will have some scoping problems. the fix is really easy, Here's what your final code will look like, I will explain stuff in the comments:
function getData() {
// This is where we store the data.
var myData;
// This will refference current object.
// You need to keep the refference of this object.
var self = this;
$.get( 'data/APPFeaturesMetaData.json' ).done(function(data) {
// the keyword `this` will not work here, because you're inside an AJAX callback.
// When you say `this`, you're actually refferencing the AJAX object
// And not the getData object.
self.myData = data;
});
return myData;
};

JavaScript/JQuery: Correct passing of local variables from a loop to anonymous ajax callback function? [duplicate]

This question already has answers here:
Javascript infamous Loop issue? [duplicate]
(5 answers)
Closed 8 years ago.
Hello there I have the following problem - within a loop I have a certain number of jQuery ajax calls - in the return of the ajax call I want to use a local variable as well as the data returned by the ajax call:
In the JavaScript class DOCache.class.js (note that I use the global variable doCache here, which also does not "feel clean" but I do not know how to pass "this"):
function DOCache() {
this.cache = new Array();
this.capi = new JsonAPI();
// loads all the properties saved in the cache object
this.loadUpdateCache = function(allLoaded) {
for(var prop in this.cache) {
// a delay will be here for each object!
this.capi.get(this.cache[prop]['url'],(function(data) {
doCache.cache[prop]['data'] = data;
doCache.cache[prop]['ready'] = true;
if(doCache.cache[prop]['loaded'] instanceof Function) {
var propLoaded = doCache.cache[prop]['loaded'];
propLoaded(data);
}
// check all initialized
if(doCache.checkAllReady()===true && allLoaded instanceof Function) {
allLoaded(doCache.cache);
}
}) (prop) // KEY: If we have this, we get the correct prop - if removed, we get the correct data - but never both
);
}
};
}
In JsonAPI.class.js:
function JsonAPI(){
this.ajax = function(request_method,api_url,data,done,fail,always) {
var jqxhr = $.ajax(
{
type:request_method,
dataType: "json",
url: JSON_BASE+api_url,
data: data
},JSON_BASE+api_url,data)
.done(function(data) {
if(done instanceof Function) {
done(data);
}
})
.fail(function(data) {
if(fail instanceof Function) {
fail(data);
}
})
.always(function(data) {
if(always instanceof Function) {
always(data);
}
});
return jqxhr;
};
this.get = function(api_url,done,fail,always) {
return this.ajax('GET',api_url,"",done,fail,always);
};
}
The problem is that I do not know how to pass the local variable from the loop (which is a different string on each loop iteration) to the actual callback function without passing it explicitly using (prop) . But if I do this I do not get the data from the callback passed in.
So the actual question is: How can I use a local variable from an iteration (which obviously end before any ajax response is returned) in an Ajax callback function?
Try to aggregate your Ajax calls within an array. Then use $.when to set the callback:
var ajaxRequests = [];
var req1 = $.ajax();
ajaxRequests.push(req1);
$.when(ajaxRequests).done(function () {});
Note, this code is untested.

JavaScript variable not being set [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Variables set during $.getJSON function only accessible within function
(6 answers)
Closed 8 years ago.
I have a small piece of js that pull some data from via ajax.
solarSystem = "test";
$.getJSON( "ajax/getLocation.php", function( data ) {
var items = [];
$.each( data, function( key, val ) {
solarSystem = val;
});
});
alert(solarSystem);
val is being set but its not outputting to the alert if i put the alert in that function it works. I assume its something to do with scope but im new to js if anyone can point me in the right direction it would be much apreciated.
While JavaScript is single-threaded, it can perform tasks asynchronously, i.e. function calls do not necessarily complete before the next line of code. AJAX (asynchronous JavaScript and XML) calls do just that. For example,
console.log("starting")
$.getJSON("path/to/resource", function (data) {
console.log("data retrieved")
})
console.log("finished")
The above code will most likely print starting and finished before it prints data retrieved. This is because $.getJSON is asynchronous. It requests a resource on a server somewhere, waits for a response, then calls the anonymous function provided as a callback, i.e. the function (data) { /* etc */ } part.
In your case, the callback function is running after alert, even though it is written above it in your code. If you want to alert(solarSystem), you'll need to place that inside of your $.getJSON call to ensure it is processed correctly:
solarSystem = "test"
$.getJSON("ajax/getLocation.php", function (data) {
var items = []
$.each(data, function (key, val) {
solarSystem = val
})
alert(solarSystem)
})
Anything inside the $.getJSON cannot access anything outside without some changes to your code. You need what is a called a callback function, and the problem is due to variable scoping.
solarSystem = "test";
function setSolarSystem(newSystem){
solarSystem = newSystem;
alert(solarSystem);
}
$.getJSON( "ajax/getLocation.php", function( data ) {
var items = [];
$.each( data, function( key, val ) {
setSolarSystem(val);
});
});

Still Having Problems Returning Value Through Function

I'm having serious problems with the function below:
function requestUploadedSearch()
{
var cookie = JSON.parse(readCookie("user_search_cookie"));
$.ajax({
dataType: "script",
async: false,
data: {
context: "search-get",
code: removeNull(cookie, cookie !== null, "code")
},
success: function(data)
{
var keywords = search_return["keywords"];
return keywords; // here is the damn problem.
}
});
}
Seams that simply nothing comes out of the function except for the undefined value and no errors are shown in the debugger.
And I'm seriously almost throwing my laptop on the wall.
If anyone could help me doing this, please answer!
Thanks in advance.
1st off: Where is the search_return variable? Why are you ignoring data?
I have a feeling this is what you want to do:
function requestUploadedSearch()
{
var cookie = JSON.parse(readCookie("user_search_cookie"));
var keywords;
$.ajax({
dataType: "json",
async: false,
data: {
context: "search-get",
code: removeNull(cookie, cookie !== null, "code")
},
success: function(data)
{
keywords = data["keywords"];
}
});
return keywords;
}
The issue is that since the Ajax call will complete at an arbitrary time in the future, you cannot simply return a value from its success handler.
One issue is that you're not actually doing anything with the data returned by the server, which seems puzzling.
The nutshell version is that you need to implement the functionality as part of the success callback. That can be done in-line, or you can create the callback function outside of the Ajax call itself and use it as the value for the success property:
function onSuccess(data) {
// Do something with the data here
}
...
$.ajax({ // etc.
success: onSuccess
};
You may also use jQuery's $.when function.
The problem is the scope you're trying to return your keywords from. The success function is called by jQuery, and you don't have any control over what jQuery does with that return value. You could do return $.ajax(... but you wouldn't get what you expect, since according to the documentation: "As of jQuery 1.5, the $.ajax() method returns the jqXHR object, which is a superset of the XMLHTTPRequest object" (http://api.jquery.com/Types/#jqXHR).
What you should do instead is set up a callback function like:
function doSomethingWithKeywords(keywords) {
// do stuff
};
and in the success function call that function:
doSomethingWithKeywords(keywords);
EDIT: Hogan's is a good solution, since your call isn't asynchronous.
The problem you are having is the return you are passing is not the return of the function -- it is the return of the event of success. Often closures (implied passing of a local variable to a function) are used to solve this problem in JavaScript.
NB I still don't think your function will work because I don't see where search_return["keywords"] is defined. But at least you won't have to worry about the closure issue. Once your success function is correct the main function will return it.
Like this:
function requestUploadedSearch()
{
var cookie = JSON.parse(readCookie("user_search_cookie"));
var returnClosure;
$.ajax({
dataType: "script",
async: false,
data: {
context: "search-get",
code: removeNull(cookie, cookie !== null, "code")
},
success: function(data)
{
// returnClosure = data["keywords"];
returnClosure = search_return["keywords"];
}
});
return returnClosure;
}

Categories

Resources