I'm really stuck with what maybe a scoping issue. Can anyone here please help me find fault with this snippet?
So I have something called surveys that are associated with a questiongroup. And i'm trying to loop through surveys to get data about the associated questiongroup except I'm really lost on where I should scope a question group.
The first function in snippet below logs qg as 'undefined' returned from the second function.
function loadData() {
var params = {};
var surveyURL = "surveys/";
var surveys, qg;
var survey_ids = [];
// this below calls the URL
var $surveyXHR = klp.api.do(surveyURL, params);
// this below is essentially $.ajax.done()
$surveyXHR.done(function(data) {
surveys = data["features"];
for(var each in surveys) {
qg = getSurveysQuestionGroup(surveys[each]["id"]);
console.log(qg);
// surveys[each]["created_by"] = qg["created_by"]["first_name"]
}
console.log(surveys);
});
}
function getSurveysQuestionGroup (surveyId) {
var params = {};
var qg;
var qgURL = "surveys/"+ surveyId + "/questiongroups/";
var $qgXHR = klp.api.do(qgURL, params);
$qgXHR.done(function(data) {
qg= data["features"];
//console.log(qg);
return(qg);
});
}
You're misunderstanding how ajax works. Your function getSurveysQuestionGroup
could be rewritten like this:
function getSurveysQuestionGroup (surveyId) {
var params = {};
var qg;
var qgURL = "surveys/"+ surveyId + "/questiongroups/";
var $qgXHR = klp.api.do(qgURL, params);
$qgXHR.done(processQgXHR);
return; // THIS is what you are getting back in loadData!
}
function processQgXHR(data) {
var qg = data["features"];
return(qg); // not being used!
}
You'll need to refactor your code. Ideally, you want to take action from inside the ajax callback function itself, not using return values. Ajax and return values typically don't mix well.
If you're familiar with multi-threaded programming, think of an ajax request as creating a new thread, not a function call.
Thanks. Initially I had this, but surveys seem to go out of scope inside the ajax.done functions. So i understand that an ajax call is async and spins off on its own. But I want to build the dependency that, for each survey, I get the question group and after that call completes I add some data into the survey. And then move to the next. However with this code below: a) The calls complete at random times, I also tried using $.ajax.always() b) The Survey object goes out of scope within the questiongroup ajax.done() call. I am just not getting my head around this. If someone could suggest a structure for these nested calls, I'd be happy to follow.
function loadData() {
var params = {};
var surveyURL = "surveys/";
var $surveyXHR = klp.api.do(surveyURL, params);
$surveyXHR.done(function(data) {
var surveys = data["features"];
for(var each in surveys) {
var qgURL = "surveys/"+ surveys[each]['id'] + "/questiongroups/";
params = {}
var $qgXHR = klp.api.do(qgURL, params);
$qgXHR.done(function(data) {
var qg = data["features"][0]; //Change this later when we have active filter
surveys[each]["created_by"] = qg["created_by"]["first_name"] + ' ' + qg["created_by"]["last_name"],
var qURL = qgURL + qg["id"] + "/questions";
var $qXHR = klp.api.do(qURL, params);
$qXHR.done(function(data) {
var questions = data["features"];
surveys[each]['questions'] = questions;
});
});
console.log(surveys[each]);
}
});
}