I am using .done () incorrectly, does not return as expected

I'm trying to use jQuery's deferred AJAX to return a JSON string that can be parsed and used, but I've coded myself in the corner and maybe messed up the logic. I expected the results of the AJAX call to be returned in the callback .done()

, and they are. I once thought I could return the result for use in the rest of the function. I know that I am missing something really obvious and simple, I just cannot tell what it is.

Here is the initial coding of the function, very strong in test mode. The JSON returns correctly to the function .done()

, but I cannot assign it outside of the function being used.

checkUserRoles = function(){
    var userRole, foo, roles, i$, len$, i;
    userRole = roleChecker();
    foo = userRole.done(function(data){
        var bar;
        bar = foo.responseText; // correctly returns the JSON data
        console.log(bar);
        return bar; //  is undefined, this is the problem
    });
    if (userRole !== false) {
        userRole = jsonDecode(userRole);
    } else {
        userRole = "";
    }
    roles = userRole.split(',');
    $("if-user-role").hide();
    for (i$ = 0, len$ = roles.length; i$ < len$; ++i$) {
        i = roles[i$];
        $("if-user-role[data-role~=" + i + "]").show();
    }
    return true;
};
this.roleChecker = function(){
    var retVal, allCookies, i$, len$, thecookie, hashedCookie, theHash, userHash, post;
    retVal = "";
    allCookies = document.cookie.split(';');
    for (i$ = 0, len$ = allCookies.length; i$ < len$; ++i$) {
        thecookie = allCookies[i$];
        if (thecookie.indexOf('userHash') >= 0) {
            hashedCookie = thecookie;
            theHash = hashedCookie.split('=');
            userHash = theHash[1];
        }
    }
    post = $.ajax({
        url: '/services/check_hash.php',
        data: {
            hash: userHash
        },
        type: "POST"
    });
    return post;
};

      

The code you see here is the result of compiling LiveScript, which we use extensively. I don't think LiveScript affects the end result, I just had to do a lot to get what I expected to be the correct JavaScript / jQuery output.

NOTE : since this is more or less the first pass in the code, foo

it is not passed along with the subsequent if statement as userRole

it was originally hard-coded for the initial one before making the function more dynamic.

How do I return foo.responseText

or bar

for use in a subsequent procedure? Do I need to introduce a procedure starting with a conditional expression if

in a function .done()

?

+3


source to share


2 answers


You are looking .then

, not .done

.

What .done

does does the action and returns the same promise. On the other hand, it then

returns a new promise that is resolved with the return value of the callback provided to it. (Assuming $.ajax

correctly resolved).

You, of course, need to put everything you subsequently do in the chain:



userRole.then(function(data){
    var bar;
    bar = foo.responseText; // correctly returns the JSON data
    console.log(bar);
    return bar;
}).then(function(role){;
  if (role != false) {
    role = jsonDecode(userRole);
  } else {
    userRole = "";
  }
//...
  return true;
});

      

You should also return

, who promise to hook him later.

+2


source


It looks like you are using synchronously deferred objects which (as you mentioned in your name) are not the target. The code that processes the user data after .done()

will execute immediately after registering this handler, so your data is not ready yet.

When you register .then()

on a deferred promise, you tell your program to run a chunk of code after the deferred object has either been resolved or rejected. The program will not wait until this deferred object is resolved or rejected, it will continue processing the code (which is the beauty of the deferred object system!)



Example:

var checkUserRoles = function () {
    var userRole = roleChecker();

    // go off and find the user data
    // but *don't wait for it before continuing code execution*
    userRole.then(function(data){

      // at this point the AJAX request has finished, and we have the data
      console.log(data);

      // put code to process the user data here
    });

    // code here is executed immediately after registering the .then handler
    // so the user data has not loaded yet
};

var roleChecker = function () {
    var defer = $.Deferred();
    var post = defer.promise();

    // simulate an AJAX Request, returns after 2 seconds
    setTimeout(function () {
      defer.resolve('user data here!');   
    }, 2000);

    return post;
};

checkUserRoles();

      

+1


source







All Articles