Shekhar Pankaj
Shekhar Pankaj

Reputation: 9145

Return in deferred.done ,does not returns from the function

I am using Deferred.Done method ,which is again called by another jquery function,

but even the point (a) {return false},is hit it still goes to point (b),

what i am doing here ?..

  function InitialMethod(isInitialCallToMethod) {

//Call using deferred method
CheckUserSession()
    .done(function (isSessionAvailable) {

        //Session data exists for end user.
        if (!isSessionAvailable) {
            //reopen modal to get user details
            OpenUserSessionModal();
            return false; --(a)
        }
    })
    .fail(function (error) {

         //reopen modal to get user details
         OpenUserSessionModal();

         //open failure div to notify user
         OpenJqueryPopup('#divDialogFailure');
         return false;
});

//Is method called for the first time,after document load?
if (isInitialCallToMethod) {

    //bind elearning tabs
    CreateElearningTabs();
}
return true; ---(b)
}

Upvotes: 1

Views: 1094

Answers (2)

Roamer-1888
Roamer-1888

Reputation: 19288

Three things to understand :

  • The two return false statements in the code both return from their respective .done() and .fail() handlers, not from the outer function.
  • Returning anything from jQuery's .done() and .fail() is pointless. Both methods are guaranteed to pass on their input promise unchanged regardless of what is returned. Only jQuery's .then() has the power to "filter" - ie to pass on a fresh promise.
  • The only way to shift a jQuery promise chain from its success path to the error path is to return a rejected promise. Returning false, even from a .then() handler will not have the same effect.

I'm guessing you want to call CreateElearningTabs() only if isSessionAvailable is truthy and isInitialCallToMethod is truthy, in which case :

function InitialMethod(isInitialCallToMethod) {
    return CheckUserSession().then(function (isSessionAvailable) {
        if (isSessionAvailable) {
            if (isInitialCallToMethod) {
                CreateElearningTabs();
            }
        } else {
            OpenUserSessionModal();
            return $.Deferred().reject(new Error('session not available')).promise();
        }
    }, function (error) {
        OpenUserSessionModal();
        OpenJqueryPopup('#divDialogFailure');
        return error;
    );
}

You could contrive a way to avoid duplicating the statement OpenUserSessionModal() (eg. the error handler could test the error) but it's hardly a big issue.

By returning a promise from InitialMethod(), the outcome is made available to the caller.

Upvotes: 3

Sirko
Sirko

Reputation: 74046

You can not simply return from a callback function and expect the original scope to respect that return statement like its own. You could return another promise from your function like this:

function InitialMethod(isInitialCallToMethod) {

  // your main function's result
  var result = jQuery.Deferred();

  //Call using deferred method
  CheckUserSession()
      .done(function (isSessionAvailable) {

          //Session data exists for end user.
          if (!isSessionAvailable) {
              //reopen modal to get user details
              OpenUserSessionModal();
              // resolve to false
              result.resolve( false );
          }

          //Is method called for the first time,after document load?
          if (isInitialCallToMethod) {
              //bind elearning tabs
              CreateElearningTabs();
          }
          // resolve to true
          result.resolve( true );
      })
      .fail(function (error) {

           //reopen modal to get user details
           OpenUserSessionModal();

           //open failure div to notify user
           OpenJqueryPopup('#divDialogFailure');

           // resolve to false
           result.resolve( false );
  });

  // return a new promise
  return result.promise(); 
}

or a little more compact

function InitialMethod(isInitialCallToMethod) {

  //Call using deferred method
  return CheckUserSession()
      .then(function (isSessionAvailable) {

          //Session data exists for end user.
          if (!isSessionAvailable) {
              //reopen modal to get user details
              OpenUserSessionModal();

              // resolve to false
              return false;
          }
          return true;
      }, function (error) {

           //reopen modal to get user details
           OpenUserSessionModal();

           //open failure div to notify user
           OpenJqueryPopup('#divDialogFailure');

           // resolve to false
           return false;

      })
      .then( function( ok ){
        if (ok && isInitialCallToMethod) {
            //bind elearning tabs
            CreateElearningTabs();
        }
        return ok;
      });
}

Note that in both cases the result is not a boolean, but a promise!

Upvotes: 3

Related Questions