Reputation: 13570
I'm having troubles to return a value from a function that is inside an object's method. How could I do this? Let me explain with code.
function ObjPerson() {
this.getPerson = function() {
function queryDB() {
//run query and pass result data to success or error functions
}
function success(data) {
//process data
return data;
}
function error(errorData) {
//process error
}
queryDB();
}
}
var person = new ObjPerson;
var userData = ObjPerson.getPerson();
The problem is that nothing is being returned from the getPerson() method. What would be the best way to do this?
Thanks!
Upvotes: 1
Views: 1350
Reputation: 105059
Return the value if this is a synchronous function
function ObjPerson() {
this.getPerson = function() {
function queryDB() {
//run query and pass result data to success or error functions
}
function success(data) {
//process data
return data;
}
function error(errorData) {
//process error
}
return queryDB(); // HERE'S THE CHANGE
}
}
var person = new ObjPerson(); // always use parentheses
var userData = person.getPerson(); // ERROR: getPerson is instance function
But if this function is async, then you should be doing it a bit differently. Unfortunately you won't be able to just call:
var userData = person.getPerson();
because by the time the assignment is made, your async call will likely not return yet... So your userData
assignment should be assigned after the async call. (tell us what async lib are you using)
But your code has other smells as well. Your inner functions queryDB
, success
and error
functions are defined within closure and for the sake of readability they should be defined as local scope variables:
var success = function (data) {
// process data
return data;
}
Upvotes: 4
Reputation: 7141
If queryDB is asynchronous, it is good advice (especially if you are using jQuery) for queryDB and hence getPerson (with modification to your code) to return a "promise" type object. From that promise you can attach more success/failure/completed type callbacks to continue processing. In jQuery, those kid of callbacks can be done with done
, fail
, always
as in:
var person = new ObjPerson;
var userDataPromise = ObjPerson.getPerson();
userDataPromise.done(function(person){
//deal with person object here
//
}).fail(function(errorobj){
//deal with error
}).always(function(){
//deal with completion
});
Now, if you were using the jQuery library, you could return the promise returned in the ajax call. That's not what I'll advise. In all likelihood, you have some strict requirements about how your person
is to be invoked. Furthermore, you really don't care to have other parts of your code know that you're doing ajax or localDB or anything... they just need access to the person
.
So here's a rough sketch about how you can complete your code to do that.
function ObjPerson() {
function getData (args,success,fail){
//somehow get your data. We'll assume it doesn't return promises
}
this.getPersonPromise = function() {
var returnedPromise = $.Deferred();
getData(args,function(data){
//success callback
//process data (assume PersonCustomData is defined elsewhere)
var person = new PersonCustomData (data)
returnedPromise.resolve(person);
}, function(error) {
//failure callback, return custom errors, or maybe
//just return original error if lazy or don't quite know all methods
//of failure or something.
var errorObj = ...
returnedPromise.reject(errorObj);
});
return returnedPromise;
}
}
var person = new ObjPerson;
var promise = ObjPerson.getPersonPromise();
person.done(function(person){
//do more stuff with PersonCustomData instance
}).fail(function(errorObj){
//oops
})
etc. That way you do not have to pass around callbacks until after the fact. Very cool.
Upvotes: 1
Reputation: 841
I've never used phonegap, but basing on its documentation:
When the executeSql method of a SQLTransaction is called it will invoke it's callback with a SQLResultSet.
executeSql, which you probably use, is asynchronous. That means, that you have to change it, for example, instead of:
var person = new ObjPerson;
var userData = ObjPerson.getPerson();
// something here using userData
you have to:
function ObjPerson() {
this.getPerson = function(requestSuccesfullCallback) {
function queryDB() {
//run query and pass result data to success or error functions
}
function success(data) {
//process data
requestSuccesfullCallback(data);
}
function error(errorData) {
//process error
}
queryDB();
}
}
function callback(userData)
{
// something here using userData
}
var person = new ObjPerson;
ObjPerson.getPerson(callback);
Upvotes: 1
Reputation: 9644
function getPerson doesn't return nothing, you should use return
in order to assign a value (note that return data
return a value for the function success
)
Upvotes: 1