Why is isOpen for sideMenu always returning false?

Hello, I have the following code in index.html to show a side menu:

<body>

      <!-- This is the Side menu options -->
    <ion-side-menus>
        <ion-side-menu-content>
            <ion-nav-bar class="bar-stable nav-title-slide-ios7">
                <ion-nav-back-button class="button-icon">
                    <span class="icon ion-ios7-arrow-left"></span>
                </ion-nav-back-button>
            </ion-nav-bar>
            <ion-nav-view></ion-nav-view>
        </ion-side-menu-content>

        <ion-side-menu side="left">
            <ion-header-bar class="bar bar-header bar-dark">
                <h1 class="title">Options</h1>
            </ion-header-bar>
            <ion-content has-header="true">
                <ion-list>

                    <ion-item href="#/montage" menu-close>
                        <span class=" item-icon-left">
                            <i class="icon ion-ios-eye"></i>
                        </span>Montage View
                    </ion-item>

                   <!-- other menu items removed for brevity -->
                    <ion-item nav-clear menu-close href="#/log">
                        <span class=" item-icon-left">
                            <i class="icon ion-clipboard"></i>
                        </span> Logs
                    </ion-item>
                </ion-list>
            </ion-content>
        </ion-side-menu>
    </ion-side-menus>




    <!--  This is where is bootstrap angular - if I don't do this, then the window jumps around
    after the status bar comes on - because the window kicked in before phonegap got ready -->

    <script>
        window.ionic.Platform.ready(function() {
            console.log("******* PLATFORM READY ****");
            angular.bootstrap(document, ['zmApp']);
        });
    </script>


</body>

Now inside app.js I have the following code to trap the Android back button and display status of side menu:

.run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, ZMDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, $fileLogger,$timeout, $ionicHistory, $window, $ionicSideMenuDelegate)
{
$ionicPlatform.registerBackButtonAction(function (event) {
             $ionicSideMenuDelegate.toggleLeft();
            console.log ("Status of SIDE MENU IS : " + $ionicSideMenuDelegate.isOpen());
        
}, 100);

The trapping works, and each time I press th back button, the menu slide toggles, but the status of isOpen is always FALSE.

This is a problem for me, because I want to exit the app if the status is TRUE - and it never shows as true.

I canā€™t figure out how to solve this problem. One could think of putting a global variable and toggling but I really donā€™t like to do that. Plus there are multiple areas in the code where the menu toggles/ My understanding is the SideMenu is a singleton - and I am only using the left part, so Iā€™m confused why this is not working. Any help?

(Updated: I event tried adding a delegate-handle to the menu, and using $ionicSideMenuDelegate.$getByHandle('sideMenu').isOpen() ā€“ makes no difference

thx

1 Like

I would say that problem is in timing.

If you toggle left sidebar, this command (.toggleLeft()) will not wait for a sidebar to open before proceeding further. Thus .isOpen() will always return false; side menu is still not fully opened.

Weā€™re talking about asynchronous process here.

1 Like

Hello @Gajotres,
I did consider that too, but it does not seem to be the problem. If it really were a timeout issue, then in my code, I am effectively toggling the side menu with each ā€œbackā€ key press. The next time I try, It should show True as the menu was already open and on back press, it would move to false (which takes time to register, if it were a timing issue)

I rewrote the code above as follows

    $ionicPlatform.registerBackButtonAction(function (event) {
             $ionicSideMenuDelegate.toggleLeft();
        $ionicSideMenuDelegate.$getByHandle('sideMenu').toggleLeft();
            $timeout ( function() {
            console.log ("Status of SIDE MENU IS : " + $ionicSideMenuDelegate.$getByHandle('sideMenu').isOpen());
            },1000);
        
}, 100);

That is, it prints the status 1 second after the operation. Still always false.

Are you willing to create a simple Plnkr.co example, you can use for example this one: http://plnkr.co/edit/hYDJL0m6SZUubUVdrdgX?p=info

Just add remove my and add your code and I will try to debug it.

@Gajotres, thank you very much.

Here is what Iā€™ve discovered on further debugging: When you press the menu icon repeatedly the ā€œtrueā€ ā€œfalseā€ of isOpen works perfectly. However, when you do the same thing inside the handler for androidā€™s back button it seems to be always reporting false, even after toggling.

Iā€™ve written a codepen but not sure how to test it, because if you hit the back button of android, it goes to the previous browser page

EDITED: What seems to be happening with the Android back button is it works for the first time ā€“ status moves from ā€˜Falseā€™ to ā€˜Trueā€™ or ā€˜Trueā€™ to ā€˜Falseā€™ but gets stuck there - does not change after the first time

try to move the registriation of the hardware backbutton functionality to a base-controller instead of the run-block

First, thanks ā€“ I learned something new about the $controller directive :smile:

Unfortunately, it does not help.
I moved the code to a base controller and injected it in another controller like so

 $controller('zmApp.BaseController', { $scope: $scope });

Then I tried switching between toggle on/off from the view associated with that controller and the results are the same. It works for the first tap and then never works - the android button handler is being called, but the status remains at True