change variable outside of xhr.onload function
Greetings,
I'm creating my own namespace api for an app i'm building but i've run into one specific annoyance.
I created a function to handle logins, here is a simplified version of my code:
var myNS = {};
myNS.user = {};
myNS.user.createSession = function( _args ){
var authorized;
var request = Titanium.Network.createHTTPClient();
request.onload = function(){
// JSON encoded server return
var response = this.responseText;
var json = JSON.parse(response);
if(json.status == 'success'){
// Update authorized variable to true
authorized = true;
} else {
authorized = false;
}
}
// Open and send xhr request
request.open(// standard open type and url);
request.send();
// Supposed to return __true__ or __false__ based on declaration given in .onload
return authorized;
};
I'm sure you can tell but what I'm wanting to do is update the authorized variable declared at the beginning of the function based on the json return on the requests onload return.
Unfortunately when I test this it always logs as blank ('').
If I give it a value to begin with such as false then it always return false so it just isn't getting updated from within onload.
2 Answers
-
Accepted Answer
An async request will continue immediately after send() to your return statement, so
return authorized
will return whatever it's set to initially. Your onload handler will get called long after the function has returned.What you'll need to do is provide a callback that can be called in your onload (or onerror) handler to alert your app to the status of the request.
In theory a synchronous request is possible, but if I remember right, at least one of iPhone or Android doesn't support it (properly, at least). It's good practice not to block on a network request, anyway, since you have no idea how long it will take and your app/UI will be completely unresponsive in the interim.
-
As written, your authorized variable is available only within the createSession function. You could use something like the following so that it's available elsewhere in the namespace:
var myNS = {}; myNS.user = {}; myNS.user.createSession = function( _args ){ myNS.authorized = false; // rest of your code
However, KT's code and suggestion also applies. Because the network operation is async, you'll need to either call a function as shown or fire an event that your app can listen for and react to.
Ti.App.fireEvent('user_authorized'); // or Ti.App.fireEvent('user_not_authorized');