$ionicHistory does not work with ion-tabs

I’m having problems using $ionicHistory on pages where ion-tabs are used. I use this to navigate to the previous view (using goBack()). When I put tabs in a view, the history is wrong, back view is two views before.

To demonstrate this I have create a demo app (plunker here) that has 4 pages/views. Page 1 -> Page 2 -> Page 3 -> Page 4. The last page has tabs on it.

This is my app code (not as long or complicated as it looks):

angular
.module("demoapp", ['ionic'])
.config(['$stateProvider', '$urlRouterProvider',
  function($stateProvider, $urlRouterProvider){
    $stateProvider
        .state('first', {
           url: '/',
           controller: 'firstController',
           templateUrl: 'first.html',
        })
        .state('second', {
           url: '/second',
           controller: 'secondController',
           templateUrl: 'second.html',
        })
        .state('third', {
           url: '/third',
           controller: 'thirdController',
           templateUrl: 'third.html',
        })
        .state('fourth', {
           url: '/fourth',
           controller: 'fourthController',
           templateUrl: 'fourth.html',
        });

    $urlRouterProvider.otherwise("/");
  }])
.factory("historyFactory", ['$ionicHistory', function($ionicHistory){
  var show = function() {
    var text = "";

    var vh = $ionicHistory.viewHistory();
    if(vh !== null) {
      text += "VIEWS=" + JSON.stringify(vh.views);
      text += "BACK=" + JSON.stringify(vh.backView);
    }

    return text;
  }

  return {
    show : show,
  }
}])
.controller("firstController", [
  '$scope',
  '$location', 
  function($scope, $location){
  $scope.next = function() {
    $location.path("/second");
  };
}])
.controller("secondController", [
  '$scope',
  '$location', 
  '$ionicHistory',
  'historyFactory', 
  function($scope, $location, $ionicHistory, historyFactory){
    $scope.next = function() {
      $location.path("/third");
    };

    $scope.prev = function() {
      $ionicHistory.goBack();
    };

    var init = function() {
      $scope.data = historyFactory.show();
    };

    init();
}])
.controller("thirdController", [
  '$scope',
  '$location', 
  '$ionicHistory', 
  'historyFactory', 
  function($scope, $location, $ionicHistory, historyFactory){
    $scope.next = function() {
      $location.path("/fourth");
    };

    $scope.prev = function() {
      $ionicHistory.goBack();
    };

    var init = function() {
      $scope.data = historyFactory.show();
    };

    init();
}])
.controller("fourthController", [
  '$scope',
  '$ionicHistory', 
  'historyFactory', 
  function($scope, $ionicHistory, historyFactory){
    $scope.prev = function() {
      $ionicHistory.goBack();
    };

    var init = function() {
      $scope.data = historyFactory.show();
    };

    init();
}]);

And this is how the view with the tabs looks like:

<ion-view>

  <ion-tabs class="tabs-balanced">
    <ion-tab title="Tab One">
      <ion-header-bar class="bar-balanced">
        <div class="buttons">
          <button class="button button-icon ion-ios-arrow-back" ng-click="prev()"></button>
        </div>
        <h1 class="title">Page 4 - Tab 1</h1>
      </ion-header-bar>

        <ion-content class="has-header">
          <h3>History</h3>
          <p>{{data}}</p>
        </ion-content>
    </ion-tab>    
  </ion-tabs>

</ion-view>

On the second page, the view history looks like this:

VIEWS=
{"002":{"viewId":"002","index":0,"historyId":"root","backViewId":null,"forwardViewId":"003","stateId":"first","stateName":"first","url":"/"},
 "003":{"viewId":"003","index":1,"historyId":"root","backViewId":"002","forwardViewId":null,"stateId":"second","stateName":"second","url":"/second"}}
BACK=
{"viewId":"002","index":0,"historyId":"root","backViewId":null,"forwardViewId":"003","stateId":"first","stateName":"first","url":"/"}

On the third page, one more view is added:

VIEWS=
{"002":{"viewId":"002","index":0,"historyId":"root","backViewId":null,"forwardViewId":"003","stateId":"first","stateName":"first","url":"/"},
 "003":{"viewId":"003","index":1,"historyId":"root","backViewId":"002","forwardViewId":"004","stateId":"second","stateName":"second","url":"/second"},
 "004":{"viewId":"004","index":2,"historyId":"root","backViewId":"003","forwardViewId":null,"stateId":"third","stateName":"third","url":"/third"}}
BACK=
{"viewId":"003","index":1,"historyId":"root","backViewId":"002","forwardViewId":"004","stateId":"second","stateName":"second","url":"/second"}

But on the fourth page, with the ion-tabs the view history remains the same.

VIEWS=
{"002":{"viewId":"002","index":0,"historyId":"root","backViewId":null,"forwardViewId":"003","stateId":"first","stateName":"first","url":"/"},
 "003":{"viewId":"003","index":1,"historyId":"root","backViewId":"002","forwardViewId":"004","stateId":"second","stateName":"second","url":"/second"},
 "004":{"viewId":"004","index":2,"historyId":"root","backViewId":"003","forwardViewId":null,"stateId":"third","stateName":"third","url":"/third"}}
BACK=
{"viewId":"003","index":1,"historyId":"root","backViewId":"002","forwardViewId":"004","stateId":"second","stateName":"second","url":"/second"}

Is this a bug with $ionicHistory when using ion-tabs or am I doing something wrong in the tabs view?

1 Like

Hi, I have the same problem with ionic tabs and ionicHistory. My flow is the following: I’m go from a state ONE without tabs to a state with tabs TWO. If i call the ionicHistory.goBack() the first time it seems to work and I go back on the state ONE. but if i navigate in tabs THREE, FOUR, TWO after this I cannot go back to the state number ONE. Many thanks.

So in short you want to make a tab switch back button return from the second tab to the first tab?

Yeah pretty sure it was working prior to the 14th update,

I think the dev teams made it firm that each tab has its own history stack
just think of it like this

each tab of your browser has its own history stack,
Would you really want it to switch tabs when you’ve pressed the back button far enough your starting at nothing?

for me yes especially in a mobile app lol,
people do tend to use the hardware backbutton instead of the one on the UI

I’ll look into it tomorrow If I can implement a custom back button,

I didn’t see the ionic tabs as browser tabs. Are they so? To me this is a single page that has a navigation “component”, the tabs, that allow me to show different content. So, in my opinion, it should be a collective history, not per tab history. At least that’s what I expected, without knowing the implementation details.

I’d try to explore the ionicHistory flow.
For me it’s ok that every single tab have a custom history and you can navigate into the stack of the single tab example state TWO. But if you go back in the stack of the tab TWO you could go to the back View that is the state ONE in History ONE.
I had follow the flow and when the stack is at the last View of the tab TWO in the back view there is correctly the View in the state ONE but if you call the method backView.go() or IonicHistory.goBack() there is a strange behavior.
I have one HistoryID for tab TWO and one HistoryId for state ONE the last view on the stack of history TWO have a backView in the stack of history ONE.
But if you call the method above the Ionic framework create a new HistoryID with another view that is a copy of last View in History TWO and have a back View that link to itself “last View in History TWO”.