Angular Cannot reattach ActivatedRouteSnapshot with a different number of children
Asked Answered
S

3

3

Here is my routing in a nativescript-angular project:

const routes: Routes = [

    {
        path: "",
        redirectTo: "/tabs/default",
        pathMatch: "full"
    },
    {
        path: "tabs",
        loadChildren: "~/app/modules/tabs/tabs.module#TabsModule"
    },
    {
        path: "login",
        loadChildren: "~/app/modules/login/login.module#LoginModule"
    },
    {
        path: "register",
        loadChildren: "~/app/modules/register/register.module#RegisterModule"
    }

];

@NgModule({
    imports: [NativeScriptRouterModule.forRoot(routes, {
        preloadingStrategy: PreloadAllModules
    })],
    exports: [NativeScriptRouterModule]
})

The scenario which leads to the error: First the app starts with tabs route, then I go to the login page, after that I go to register and then again I go to tabs page (and clean the history). After that if I go to login page again and get back to previous one (tabs page), the error occurs.

The error:

JS: Error: Cannot reattach ActivatedRouteSnapshot with a different number of children
JS:     at setFutureSnapshotsOfActivatedRoutes (file:///data/data/org.nativescript.tns57/files/app/tns_modules/@angular/router/bundles/router.umd.js:1950:19) [angular]
JS:     at setFutureSnapshotsOfActivatedRoutes (file:///data/data/org.nativescript.tns57/files/app/tns_modules/@angular/router/bundles/router.umd.js:1954:13) [angular]
JS:     at createNode (file:///data/data/org.nativescript.tns57/files/app/tns_modules/@angular/router/bundles/router.umd.js:1935:17) [angular]
JS:     at file:///data/data/org.nativescript.tns57/files/app/tns_modules/@angular/router/bundles/router.umd.js:1975:20 [angular]
JS:     at Array.map (<anonymous>) [angular]
JS:     at createOrReuseChildren (file:///data/data/org.nativescript.tns57/files/app/tns_modules/@angular/router/bundles/router.umd.js:1958:30) [angular]
JS:     at createNode (file:///data/data/org...

Any idea?

Swann answered 20/5, 2019 at 10:2 Comment(10)
Did you try without cleanHistory ?Ebbarta
@Ebbarta Still I get the error wihtout clearHistory.Swann
@Ebbarta You can test with this repo: github.com/NativeScript/login-tab-navigation-ng/issues/7Swann
do you use RouterModule.forRoot to initialize this or this.router.resetConfig ? can you please add the section of the module where you use this array?Savitt
@Savitt I use forRoot to initialize. Updated the content. Please see again. Thanks.Swann
@VahidNajafi Are you using RouteReuseStrategy? Can you share your implementation?Orange
@Orange No, I don't use RouteReuseStrategy at all. (just tested the one in the answer and it didn't work)Swann
Hav you tried removing the preloading strategy to see if it works without it ?Admiral
@Maryannah The main repo doesn't contain the preloading strategy at all: github.com/NativeScript/login-tab-navigation-ng/blob/master/src/…Swann
@VahidNajafi Can you update the playground play.nativescript.org/?template=play-ng&id=HYGiOH to reproduce the issue?Ebbarta
D
1

Try change the first route

{
    path: "",
    redirectTo: "tabs",
    pathMatch: "full"
}

and set your TabsModule like that

const routes: Routes = [    
    {
        path: "",
        redirectTo: "default",
        pathMatch: "full"
    },
    {
        path: "default",
        component: YourDefaultComponent
    }
    ...
];

UPDATE : If you get an same error, you can use AttachDetachReuseStrategy

import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';

interface RouteStorageObject {
    snapshot: ActivatedRouteSnapshot;
    handle: DetachedRouteHandle;
}

export class CustomReuseStrategy implements RouteReuseStrategy {


    handlers: { [key: string]: RouteStorageObject } = {};

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        if (!route.routeConfig) return null;
        if (route.routeConfig.loadChildren) return null;
        return this.handlers[route.routeConfig.path];
    }

    .....

}

then I make shouldDetach function also check for loadChildren to prevent RouteReuseStrategy save wrong ActivatedRouteSnapshot:

shouldDetach(route: ActivatedRouteSnapshot): boolean {
    if (!route.routeConfig || route.routeConfig.loadChildren) {
        return false;
    }
    return true;
}

Ofcourse, modify your AppModule

@NgModule({
    imports: [...],
    providers: [
        {provide: RouteReuseStrategy, useClass: CustomReuseStrategy}
    ],
    ....
)}
export class AppModule {
}
Dichotomous answered 22/5, 2019 at 11:21 Comment(5)
Thanks for your answer. But still, I get the same error.Swann
You mean I must have a CustomReuseStrategy and add it to my providers?Swann
What is this.handlers? Where do you define it?Swann
I did it. But the result is the following: Tabs get loaded first, then I go to login page, the from login I go to register. Then I come back, in login animations reinitialize (this shouldn't be done when I press back button) , then I press back again to go back to tabs, now content of tabs disapear.Swann
I used retrieve and shouldDetach as you mentioned, and for store I do nothing, for shouldAttach I return false, and for shouldReuseRoute I return future.routeConfig === curr.routeConfig;. Is it ok?Swann
E
0

Try updating to nativescript-angular to version 7.2.4 . The repo link that you posted is using version 7.2.3 that contains some issue with routing.

https://github.com/NativeScript/nativescript-angular/pull/1740

Ebbarta answered 27/5, 2019 at 6:37 Comment(3)
Thanks. But I still get the same error after updating nativescript-angular to version 7.2.4. Could you be able to reproduce the issue?Swann
is it possible for you to create the playground?Ebbarta
@VahidNajafi Have you tried disabling Route Resue by adding this import {Router} from "@angular/router"; this.router.routeReuseStrategy.shouldReuseRoute = function(){ return false;};Ebbarta
O
0

Did you try passing the relativeTo extras? Weirdly this worked for me and I can't figure out how and why.

this.routerExtension.back({relativeTo: this.activatedRoute});

Like this.

Oodles answered 27/7, 2020 at 12:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.