Reputation: 784
I have an Angular 12 app with a lazy loaded module. The different children routes are protected by some different guards. I can navigate as expected through the app without any problem, but if I directly hit the url of any of the children of the lazy loaded module, then I got in the console the error "Cannot activate an already activated outlet" and the app craches.
I targeted the problem in my guard, if I comment the this.router.navigate(["/shop"]);
line of my guard, then I don't get the error (but then I don't have the expected behavior if the guard: it blocks well the page but don't navigate to another url...)
I tried the solution below but it doesn't solve the error (even if it concerns also a lazy loading module, the problem was about named outlets which I don't have) Angular 7 - Multiple outlets : Error: Cannot activate an already activated outlet
Here is my root routing file app.routes.ts with the 2 lazy modules for the whole app, which is imported in the app.module.ts imports by the classic RouterModule.forRoot(APP_ROUTING)`
// file: app.routes.ts
// native modules
import { Routes } from "@angular/router";
export const APP_ROUTING: Routes = [
// empty url redirects top the shop
{ path: "", redirectTo: "shop", pathMatch: "full" },
// shop as lazy loaded module
{
path: "shop",
loadChildren: () => import("./shop/shop.module").then(m => m.ShopModule)
},
// backoffice as lazy lloaded module
{
path: "back",
loadChildren: () =>
import("./backoffice/backoffice.module").then(m => m.BackofficeModule)
},
// Any non existing url redirects to the shop
{ path: "**", redirectTo: "shop" }
];
Here are the routes of the lazy module:
// shop.routes.ts file
export const SHOP_ROUTES: Routes = [
{
path: "",
component: ShopWorkspaceComponent,
// prettier-ignore
children: [
{ path: '', component: HomepageComponent },
{ path: 'connexion', canActivate:[AnonymousGuard], component: ShopLoginComponent },
{ path: 'inscription', canActivate:[AnonymousGuard], component: ShopRegisterComponent },
{ path: 'profil', canActivate:[ClientGuard], component: ShopProfileComponent }
]
}
];
Here is the AnonymousGuard canActivate:
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> {
return this.authStore.pipe(
withLatestFrom(this.authStore.pipe(select(isAnonymousSelector))),
map(([, isAnonymous]) => {
if (isAnonymous) return true;
else {
// if I comment the router.navigate below I don't have the error
this.router.navigate(["/shop"]);
return false;
}
})
);
}
}
and one of the lazy module with the Router.forChild (minus imports):
// shop.module.ts file, lazy loaded
const COMPONENTS = [
ShopWorkspaceComponent,
HomepageComponent,
ShopMenuComponent,
ShopRegisterComponent
]
const MODULES = [
// native modules
RouterModule.forChild(SHOP_ROUTES),
BasicModule,
// feature modules
ShopLoginModule,
ShopProfileModule,
];
// Shop module
@NgModule({
declarations: COMPONENTS,
imports: MODULES
})
export class ShopModule {}
Upvotes: 0
Views: 968
Reputation: 2396
Try updating your canActivate
like this:
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.authStore.pipe(
withLatestFrom(this.authStore.pipe(select(isAnonymousSelector))),
map(([, isAnonymous]) => {
if (isAnonymous) return true;
else {
return this.router.navigate(["../shop"]);
}
})
);
}
}
Upvotes: 0