$ionicSideMenuDelegate.toggleRight() History Issue ALREADY SOLVED (Sort of)


#1

Hi everyone! I’m posting a work-around for $ionicSideMenuDelegate.toggleRight() not toggling the menu (called from inside a popover, in case it matters). If anyone has this same issue with the $ionicSideMenuDelegate I hope to save them time. If anyone has a better solution, please let me know!

The app I’ve created is multi-paged. The expected behavior is a user can navigate to a page, open a popover and press a button on the popover to toggle open the sidemenu from the right. When the user visits the page with the side menu button with any history in the $ionicHistory object, the menu does not open. If the user refreshes the page, thereby clearing the history, the side menu opens.

This was my broken call.

function openLookUp(){

$ionicSideMenuDelegate.toggleRight();
Analytics.track(“Opened LookUp Panel”);
}

The delegate calls this function.

function instanceMethodCaller(methodName) {
return function caller() {
var handle = this.handle;
var args = arguments;
var foundInstancesCount = 0;
var returnValue;

      this._instances.forEach(function(instance) {
        if ((!handle || handle == instance.$$delegateHandle) && instance.$$filterFn(instance)) {
          foundInstancesCount++;
          var ret = instance[methodName].apply(instance, args);
          //Only return the value from the first call
          if (foundInstancesCount === 1) {
            returnValue = ret;
          }
        }
      });

      ...
      return returnValue;
    };
  }

The second parameter that must be evaluated as true before foundInstanceCount is incremented is “instance.$$filterFn(instance)” is called, which is the following.

var deregisterInstance = $ionicSideMenuDelegate._registerInstance(
self, $attrs.delegateHandle, function() {
return $ionicHistory.isActiveScope($scope);
}
);

Which goes to ->

isActiveScope: function(scope) {
if (!scope) return false;

  var climbScope = scope;
  var currentHistoryId = this.currentHistoryId();
  var foundHistoryId;

  while (climbScope) {
    if (climbScope.$$disconnected) {
      return false;
    }

    if (!foundHistoryId && climbScope.hasOwnProperty('$historyId')) {
      foundHistoryId = true;
    }

    if (currentHistoryId) {
      if (climbScope.hasOwnProperty('$historyId') && currentHistoryId == climbScope.$historyId) {
        return true;
      }
      if (climbScope.hasOwnProperty('$activeHistoryId')) {
        if (currentHistoryId == climbScope.$activeHistoryId) {
          if (climbScope.hasOwnProperty('$historyId')) {
            return true;
          }
          if (!foundHistoryId) {
            return true;
          }
        }
      }
    }

    if (foundHistoryId && climbScope.hasOwnProperty('$activeHistoryId')) {
      foundHistoryId = false;
    }

    climbScope = climbScope.$parent;
  }

  return currentHistoryId ? currentHistoryId == 'root' : true;
}

};

This always evaluated to false if there was any history in the $ionicHistory object. Using $ionicHistory’s methods to clear history did not work.

I suspect this problem has to do with calling the delegate from a popover, because I believe that popovers affect the $ionicHistory object. Regardless, I could not fix the issue and I did not want to change the source. I implemented a work-around, and this is my working call.

function openLookUp(){

/*
The default toggleRight() has a convoluted error with $ionicHistory.isActiveScope($scope)
The function will NEVER return true if the user has navigation history (it works if they have refreshed on the page and have “no” history)
Using ._instances[0] grabs the first & only instance of the side menu in the app (as of 9/3/2015) and manually initiates the toggleRight()
*/
$ionicSideMenuDelegate._instances[0].toggleRight();
Analytics.track(“Opened LookUp Panel”);
}

I hope this helps someone C: If you think i’m nuts and know a better way, please let me know!