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!