Right I've got this JS function
function AreaCompare(sql, UIDfield, Geogname, Table, sourceName, sourceID, destName, destID){
CompareObj = {};
CompareObj.sName = sourceName;
CompareObj.sID = sourceID;
CompareObj.dName = destName;
CompareObj.dID =destID;
sql.execute("select ST_Area(the_geom::geography)/1000000 as SA FROM "+Table+" where "+UIDfield+"="+sourceID)
.done(function(data) {
CompareObj.sArea=JSON.stringify(data.rows[0].sa);
sql.execute("select ST_Area(the_geom::geography)/1000000 as DA FROM "+Table+" where "+UIDfield+"="+destID)
.done(function(data) {
CompareObj.dArea=JSON.stringify(data.rows[0].da);
alert(JSON.stringify(CompareObj));
return CompareObj;
})
})
}
It appears to work correctly and the alert box flashes up with a readable version of the object that is as expected.
however when I examine the returned object it is undefined, essentially empty/null.
What trick am I missing a trick here? It originally thought it was something related to scope and the done
function.
I did allot of research and I realised I needed to nest the CartoDB SQL statements, but that didn't fix the problem.
Any suggestions?
-
Have you tried to declare CompareObj as a global variable?toms– toms2015年01月20日 04:00:47 +00:00Commented Jan 20, 2015 at 4:00
-
Also, the beauty of browser based code is debugging. Run this is Chrome, or Firefox, and put a breakline at the return statement. Then when you run the function, it will pause there and you can inspect the variable to see if it contains what you expect it to.Alex Leith– Alex Leith2015年01月20日 04:13:44 +00:00Commented Jan 20, 2015 at 4:13
-
@toms yep I tried that, some success, It will give me the object but will not contain the key/value for the values set inside the 'done' functions. I think this is because CartoDB uses an AJAX for the SQL queries and java script executes the other code while waiting on a response.Omar Sarhan– Omar Sarhan2015年01月20日 16:46:31 +00:00Commented Jan 20, 2015 at 16:46
1 Answer 1
Maybe this pattern will help? If alert
on .done
is showing the expected result, you should be able to pass CompareObj
to a new function (also from within the .done
function), and evaluate the global CompareObj from there. No need to worry about asynchronous response in that case, since the new function won't execute until AJAX is done.
// declare this as a global variable
CompareObj = {};
function AreaCompare(sql, UIDfield, Geogname, Table, sourceName, sourceID, destName, destID){
CompareObj.sName = sourceName;
CompareObj.sID = sourceID;
CompareObj.dName = destName;
CompareObj.dID =destID;
sql.execute("select ST_Area(the_geom::geography)/1000000 as SA FROM "+Table+" where "+UIDfield+"="+sourceID)
.done(function(data) {
CompareObj.sArea=JSON.stringify(data.rows[0].sa);
sql.execute("select ST_Area(the_geom::geography)/1000000 as DA FROM "+Table+" where "+UIDfield+"="+destID)
.done(function(data) {
CompareObj.dArea=JSON.stringify(data.rows[0].da);
// if you are getting what you want here, pass the object to a new function and do something with it
alert(JSON.stringify(CompareObj));
// return CompareObj;
useResult(CompareObj);
})
})
}
// new function to use the result
function useResult(CompareObj) {
// do something with the result here...
}
-
Thanks Toms, you are a great help. My code is a modified version of yours now: dropbox.com/s/emvzlkq44gbtc29/Compare.js?dl=0 Now line 21 displays the correct answer as an alert, but in my main script block if I call:
AreaCompare(sql, UIDfield, Geogname, Table, sourceName, sourceID, destName, destID)
then callalert(GetBiggest())
Ill get an
undefined` back. In fact if I have both alerts set up I get theundefined
before the correct alert generated from within theAreaCompare
function (as per line 21) I`m no whizz at programming but I should be able to do this. :/Omar Sarhan– Omar Sarhan2015年01月21日 02:58:12 +00:00Commented Jan 21, 2015 at 2:58