Alexander Bunting Alexander Bunting - 3 months ago 9
Javascript Question

Functions, objects and anonymous functions

I have this code below.

var user = new user();

function user() {

// returns true if the account is password protected
function isPasswordProtected(data, callback) {
//check if the account is a password protected account, and if so request the password.
$.post('user_functions/ifpasswordprot.php', {uid: data['uid']}, function(data) { return callback(data);});
}

// function that returns 1 if the user is password protected
this.getPPStatus = function() { return isPasswordProtected({uid: this.userid}, function(data) { return data; }); };

}


This is designed to create an store a user object, which can be referenced from elsewhere within the site. There is more to it than this, but that is the code relevant here.

From another page I am trying to find out if the user that is logged in has protected their account with a password, as thus:

alert(user.getPPStatus());


However this always comes out as
undefined
.

I'm not expert on objects in JavaScript, nor on the user of anonymous functions. Can anybody please explain why this wouldn't work? It seems to be like there are enough returns at each turn that it should be OK.

SOLUTION

This is an async problem, so:

var user = new user();

function user() {
// returns true if the account is password protected
function isPasswordProtected(data, callback) {
//check if the account is a password protected account, and if so request the password.
$.post('function/get-ifpasswordprotected.php', {uid: data['uid']}, function(data) { callback(data);});
}

// function that returns 1 if the user is password protected
this.getPPStatus = function(**callback**) { isPasswordProtected({uid: this.userid}, **callback**); };

}


and then

user.getPPStatus(function(result) {
**DO STUFF HERE**
});


absolutely no idea if this is good javascript or not but hey, it works... :)

Answer

There are three reasons why that won't work:

  1. $.post is asynchronous by default, so if isPasswordProtected uses it to get the information, it cannot return the flag, as when it returns it doesn't have the result yet. See How do I return the response from an asynchronous call? for details.

  2. Even if the $.post were synchronous (which it can be with an option, but it's a bad idea), $.post doesn't make any use of the return value of its callback, so your return in that callback doesn't do anything.

  3. Even if $.post were to return the result of the callback if it were synchronous (it doesn't), isPasswordProtected never sets a return value (in that code, there's no return from isPasswordProtected, only from the callback to $.post).

The link above explains how to change getPPStatus and isPasswordProtected to address the asynchronous issue, which also by its nature resolves the issue with the returns.