Skip to content

Router outlet inside ngIf getting activated with old route #49457

@jancabadaj

Description

@jancabadaj

Which @angular/* package(s) are the source of the bug?

router

Is this a regression?

No

Description

When child router-outlet is created after route is changed to no longer include this child, then the outlet remains incorrectly activated.

In the example below, parent component initialization takes 1000ms. If router navigates to 'Child' and then back to 'Parent' in lower time (500ms), then router-outlet with child gets activated at 1000ms even though the route was already changed. Since the outlet is activated, navigating back to 'Child' results in exception.

If I change the time from 500ms to more than 1000ms, then child outlet is correctly deactivated.

  breakApp() {
    this.router.navigate([`Parent/Child`], { relativeTo: this.activatedRoute });
    setTimeout(() => {
      this.router.navigate(['Parent'], { relativeTo: this.activatedRoute });
    }, 500);
  }

///////////////////////////////////////////////////

@Component({
  template: `<p>parent</p>
            <div *ngIf="initialized">
              <router-outlet></router-outlet>
            </div>`
})
export class ParentComponent {
  initialized = false;

  ngOnInit(): void {
    setTimeout(() => {
      this.initialized = true;
    }, 1000);
  }
}

///////////////////////////////////////////////////

@Component({
  template: '<p>child</p>',
})
export class ChildComponent { }

///////////////////////////////////////////////////

const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: 'Parent',
        component: ParentComponent,
        children: [
          {
            path: 'Child',
            component: ChildComponent,
          },
        ],
      },
    ],
  },
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }

The issue can be seen in provided stackblitz demo. Clicking Break button results in child outlet remaining in activated state. In such state it is not possible to switch between children. After navigating back to root page Parent component gets destroyed and problem is resolved.

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-dedznl

Please provide the exception or error you saw

Error: NG04013: Cannot activate an already activated outlet

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 15.1.6        
Node: 16.18.1
Package Manager: npm 8.19.2
OS: win32 x64

Angular: 15.2.3
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1502.4
@angular-devkit/build-angular   15.2.4
@angular-devkit/core            15.2.4
@angular-devkit/schematics      15.1.6
@angular/cli                    15.1.6
@schematics/angular             15.1.6
rxjs                            7.8.0
typescript                      4.9.5

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions