Ion-nav-view has no children after $state.go


#1

We use ionic framework within an cordova app mainly on android devices.
We face some strange behaviour: sometimes when we switch the view using

$state.go()

the old ion-view DOM element gets removed from it parent ion-nav-view but the new ion-view does not get appended. Executing

$state.reload()

does append the current ion-view to the ion-nav-view parent again.
Caching and animations are turned of.


#2

a little codepen would be nice to see your states and routings.

Does not recognized this behave in my apps.


#3

Sample situation

Problem is that it only occurs on android devices not in a desktop browser.
We faced that behaviour e. g. when

  • app is put to background
  • wifi is turned off
  • wifi is turned on again
  • resume to app
  • wait till cordova-plugin-network-information recognized wifi connection
  • switch view, or do a $state.reload()

There might be other cases and and it might depend on cordova web view.

How $state is configured?

In main ng module:

angular.module("app", ["app.lib", "app.features"])
.config(function ($stateProvider, $urlRouterProvider) {
    // if none of the above states are matched, use this as the fallback
    $urlRouterProvider.otherwise('apploadpage');
})

Than in some other angular module:

angular
    .module('app.login_user')
    .config(function ($stateProvider) {
        $stateProvider
            .state('login_user', {
                url:         "/login_user",
                templateUrl: "js/features/login_user/start/login_user.html",
                controller:  'login_userController as vm'
             })
    });

I had a look into the $state source to check were the from ion-view element is removed from its parent ion-nav-view and where the new ion-nav child is appended. If I know that I can try to set a breakpoint and debug.

Maybe you can give me some help to find the places in code.


#4

Today I made some further investigations using MutationObserver:

Code

var $rootScope = angular.element(document.body).injector().get("$rootScope");

$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
     console.log('--> entering', toState.name, 'with', toState.controller, '(from:', fromState.name, ')');
});

var target = document.body.getElementsByTagName("ion-nav-view")[0];

var config = {
    childList: true
}

var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        console.log("********************************************************************************");
        console.log("Type:", mutation.type);
        console.log("target:", mutation.target);
        console.log("target.children:", mutation.target.children);
        console.log("target.children.length:", mutation.target.children.length);
        console.log("addedNodes:", mutation.addedNodes);
        console.log("removedNodes:", mutation.removedNodes);
    });    
});

observer.observe(target, config);

Output

entering login_user with login_userController as vm (from: start ) 
login_userController login_user
********************************************************************************
Type: childList
target: <ion-nav-view class=​"view-container" nav-view-transition=​"none" nav-view-direction=​"forward" nav-swipe>​</ion-nav-view>​
target.children: [ion-view.pane, ion-view.pane, item: function, namedItem: function]
target.children.length: 2
addedNodes: [ion-view.pane, item: function]
removedNodes: [item: function]
********************************************************************************
Type: childList
target: <ion-nav-view class=​"view-container" nav-view-transition=​"none" nav-view-direction=​"forward" nav-swipe>​</ion-nav-view>​
target.children: [item: function, namedItem: function]
target.children.length: 0
addedNodes: [item: function]
removedNodes: [ion-view.pane, item: function]
********************************************************************************
Type: childList
target: <ion-nav-view class=​"view-container" nav-view-transition=​"none" nav-view-direction=​"forward" nav-swipe>​</ion-nav-view>​
target.children: [item: function, namedItem: function]
target.children.length: 0
addedNodes: [item: function]
removedNodes: [ion-view.pane, item: function]

Conclusion

Is this case that does occure onyl sometimes both childs ion-view get removed.
$stateChangeSuccess is triggered before any DOM element operation is executed.