The “back” navigation button visible when using resolve in state configuration

Hi guys, I’ve got problem with the side menu (sidemenu ionic template), when using resolve in state configuration. When the resolve evaluation is longer than the expire option (300ms) in menuClose directive (very often in real app), then the $ionicHistory.nextViewOptions (set in the menuClose directive) are probably no longer valid and the “back” button is visible on the destination view (in this case templates/playlists.html). My app.playlists state configuration is:

.state('app.playlists', {
  url: "/playlists",
  views: {
    'menuContent': {
      templateUrl: "templates/playlists.html",
      controller: 'PlaylistsCtrl',
      resolve: {
        playlists: ['$http', function ($http) {
          return $http.get('/playlistsResourceUrl');
        }]
      }
    }
  }
})
1 Like

Hi guys, any advice on this, please? Is using resolve recommended in ionic? Thank you.

I think that you have same problem than me. When I navigate to playlists view from another view (in the same level) the back button appears instead of menu button.

image

I’ve only added this code in a project from sidemenu template:

//File: app.js
.state('app.playlists', {
  url: "/playlists",
  views: {
    'menuContent': {
      templateUrl: "playlists.html",
      controller: 'PlaylistsCtrl',
      resolve: {
        data: function($timeout, $q){
          var dfd = $q.defer();

          $timeout(function(){dfd.resolve("Async Hello world!")},500);

          return dfd.promise;
        }
      }
    }
  }
})

What Do we wrong?

P.S. If I remove the async code or change delay to < 300ms all works fine.

I’ve created a codepen with a example: http://codepen.io/jonathanmartinez/pen/yymKbK

Thank you!

Can someone help us? @mhartington
Thanks guys.

Would you mind opening an issue for this? It may be related to our animations, but that could lead to a big change, so I’d like to get the other teams members opinion

I am also facing same problem, do i need to open an issue for this?.

+1

Does anyone have a temporary workaround for this?

+1 I have the same problem :no_mouth:

same issue here, resolve does break the history and back button show up. the issue is reported like 2 months ago

it reappears in the last version. - 1.1.0

It doesn’t work in 1.1.1
Is there any temporary fix beside resolving data in the controller instead of the route ?

I’m seeing some similar behavior in 1.2.4 with the side menu:

Let’s say I have 2 side menu items, A and B, where A is the default route and B is a sibling route. Route A has a resolve block that fetches data from a remote API and returns a promise. Route B does not have a resolve block.

When I navigate from A to B, via the side menu, all is well. However, when I navigate back to A from B, it appears the view loads twice–occasionally–causing the hamburger menu to disappear. This seems to be a race condition, as it becomes a more probable outcome as the remote API response times grow.

Cheers,
Tim

I solved this problem decorating the closeMenu directive. This directive has a 300 millisenconds hardcoded delay that cause apparently this problem. I solved listening the event $stateChangeSuccess and waiting more 100 milliseconds:

(function () {
  'use strict';

  /** @ngInject */
  function config($provide) {

    /** @ngInject */
    function closeMenuDirectiveDecorator($delegate, $ionicHistory, $timeout) {
      var directive = $delegate[0];

      var link = function (scope, element) {
        element.bind('click', function() {
          var sideMenuCtrl = element.inheritedData('$ionSideMenusController');
          if (sideMenuCtrl) {
            $ionicHistory.nextViewOptions({
              historyRoot: true,
              disableAnimate: true,
              expire: 500
            });

            var fn = scope.$on('$stateChangeSuccess', function($event) {
              $timeout(function(){
                $ionicHistory.nextViewOptions({
                  historyRoot: false,
                  disableAnimate: false
                });
              }, 100);

              fn();
            });

            sideMenuCtrl.close();
          }
        });
      };

      directive.compile = function() {
        return function(scope, element) {
          link.apply(this, arguments);
        };
      };

      return $delegate;
    }

    $provide.decorator('menuCloseDirective', closeMenuDirectiveDecorator);
  }

  angular
    .module('app')
    .config(config);

})();

For me this decorator works, but feels free to improve it.