angular: Angular 5 - "Error: Cannot activate an already activated outlet" when named outlets are used in children
I’m submitting a…
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
As stated here on stackoverflow when you have a routing configuration like:
export const routes = [
{
path: '',
component: IndexComponent,
children: [
{
path: 'home',
children: [
{ path: '', component: FirstComponent, outlet: 'first', data: { state: 'a' } },
{ path: '', component: SecondComponent, outlet: 'second', data: { state: 'b' } }
]
},
{
path: 'about',
children: [
{ path: '', component: FirstComponent, outlet: 'first', data: { state: 'b' } },
{ path: '', component: SecondComponent, outlet: 'second', data: { state: 'a' } }
]
}
]
}
And you are navigating from /home
to /about
using a link <a routerLink="['/about']">about</a>
it throws the following error:
ERROR Error: Uncaught (in promise): Error: Cannot activate an already activated outlet
Error: Cannot activate an already activated outlet
Expected behavior
The expected behavior would be that it navigates to /about
and the router populates the named outlets with the new components (taking internally care of deactivation/activation of outlets).
Minimal reproduction of the problem with instructions
Just a simple app, with routing a named outlets with the configuration above.
What is the motivation / use case for changing the behavior?
It’s a show stopper.
Environment
Angular version: 5.0.3
Browser:
- [x] Chrome (desktop) version XX
- [x] Chrome (Android) version XX
- [x] Chrome (iOS) version XX
- [x] Firefox version XX
- [x] Safari (desktop) version XX
- [x] Safari (iOS) version XX
- [x] IE version XX
- [x] Edge version XX
Others:
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 35
- Comments: 43 (3 by maintainers)
Links to this issue
Commits related to this issue
- fix(router): deactivate outlet if already activated when calling activateWith Instead of throwing an error, we are now able to deactivate the outlet before activating it again with a new route. This ... — committed to gigadie/angular by deleted user 7 years ago
- fix(router): deactivate outlet if already activated when calling activateWith Instead of throwing an error, we are now able to deactivate the outlet before activating it again with a new route. This ... — committed to gigadie/angular by gigadie 7 years ago
- Angular router build with fix for #20694 — committed to Riobe/angular by deleted user 7 years ago
- fix(router): deactivate outlet if already activated when calling activateWith Instead of throwing an error, we are now able to deactivate the outlet before activating it again with a new route. This ... — committed to gigadie/angular by gigadie 7 years ago
- fix(router): correctly deactivate children with componentless parent During route activation, a componentless route will not have a context created for it, but the logic continues to recurse so that ... — committed to atscott/angular by atscott 4 years ago
- fix(router): correctly deactivate children with componentless parent During route activation, a componentless route will not have a context created for it, but the logic continues to recurse so that ... — committed to atscott/angular by atscott 4 years ago
- fix(router): correctly deactivate children with componentless parent During route activation, a componentless route will not have a context created for it, but the logic continues to recurse so that ... — committed to atscott/angular by atscott 4 years ago
- fix(router): correctly deactivate children with componentless parent During route activation, a componentless route will not have a context created for it, but the logic continues to recurse so that ... — committed to atscott/angular by atscott 4 years ago
- fix(router): correctly deactivate children with componentless parent (#40196) During route activation, a componentless route will not have a context created for it, but the logic continues to recurse... — committed to angular/angular by atscott 4 years ago
…Ah, Do not add
<route-outlet></route-outlet>
to any Structural Directive(such as ngIF), angular cannot deactivate<route-outlet/>
if it is not rendered 😆We’ve adopted angular at my place of work, and we’re relying on this technique for routing because we don’t want to embed router-outlet information into the url. Until this works we’ll have to rely on a fork of @angular/router that has the fix in the pull request in it to keep moving forward.
I guess it’s a more involved way of +1’ing, but I just want it clear that there are others that need this fix too.
You need to change a little bit the routes. One of the 2 child routes should not be named. And of course the IndexComponent should also have two outlets one named and one without name.
Come on, guys! It’s been more than one year since creating of the issue! >_<
In my situation, Angular misactivated a child route, path changed and Angular tried to reactivate it again. The temporary solution is to attach to that problematic router-outlet’s activate event, check the activation logic yourself and if the logic fails, call deactivate on the RouterOutlet instance.
This guy’s got a working answer: https://stackoverflow.com/a/55742986/3000466. The workaround is deactivating manually the router on each event:
This a popular ignore case (seems like) or…? Because it is NOT just named outlets any longer
And if i name them, the behavior doesn’t change
I have the same problem but I strongly disagree with replacing the error with a call to
deactivate()
because that is a bandaid fix that only hides the underlying problem.A better fix would be changing the router to not call
activateWith
again if the outlet is already activated.It would be better if someone could investigate how it’s possible that named outlets remain activated after navigating away from them.
Finally! Adding a primary (unnamed), empty router-outlet to my template completely fixed it. Thank you
What method is _shouldActivate ? can you post this also please?
The suggestion above finally solved it for me. It seems like the angular router doesn’t deactivate named router outlets if it can’t first deactivate an un-named one, even if the un-named router-outlet doesn’t exist in the template. As long as it is present in the router configuration, it’s gonna work. Ex:
This doesn’t work:
But this does:
Hi, struggled a while with this myself, but found a way to structure my routes so that the issue no longer occurred, have posted an example of my routes below, hope this can help some of you.
Also hitting this issue, but only when webpack recompiles and on screen load i get Cannot activate an already activated outlet albeit using Ionic 4/Angular.