1

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)
}
Shekhar Pankaj
  • 9,065
  • 3
  • 28
  • 46

2 Answers2

3

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!

Sirko
  • 72,589
  • 19
  • 149
  • 183
3

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.

Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
  • now, i am in dilemma,which answer to mark as accepted,both answered my query in different ways – Shekhar Pankaj Aug 04 '15 at 12:09
  • If it helps, the two solutions differ in how the outcome is reported to the caller. Sirko: A `CheckUserSession()` error will cause the returned promise to take the error path, but "session not available" will cause it to take the success path. Roamer: A `CheckUserSession()` error and "session not available" will both cause the returned promise to take the error path. It may not matter to you but if it does, that's the main distinguishing difference between the two answers. – Roamer-1888 Aug 05 '15 at 00:02