3

Fellow developers,

I've got an app that makes use of multiple layouts (eg. the login route has no navbar, but dashboard routes have a navbar + footer). What I'm doing is adding the layout to use in the data property in the route definition, so for example:

const routes: Routes = [
  {
    path: 'login',
    component: LoginComponent,
    data: { layout: Layouts.FooterOnly }
  },
];

The layout to use is then set in the AppComponent on route changes. Something strange is happening though and it's a bit tough to explain exactly what's going wrong. The bug can be reproduced by doing the following in the sample repo below:

  1. Navigate to Login route from Dashboard route.
  2. Navigate back to Dashboard route.
  3. Navigate to Users route.

For some reason, the router outlet then stops working and always displays the content of the Dashboard page (ie. dashboard works!). There's no errors and I can't pinpoint why this is happening. Can someone shed some light on how on Earth to handle this?

Sample repo with the issue: https://stackblitz.com/edit/routing-layouts-xv1s8k

L. Berger
  • 266
  • 2
  • 15

2 Answers2

2

because you have two router-outlet

you can put your router outlet in an ng-template and pass it to your layout components

Here 's your repo adapted https://stackblitz.com/edit/routing-layouts-jzgekp

JiBi
  • 378
  • 1
  • 6
  • Perfect, thank you!! Picked yours since it doesn't force CD. It's a little weird to me how `changeDetectorRef.detectChanges()` doesn't update the view, but `setTimeout` does like in the other answer. – L. Berger Mar 10 '21 at 01:19
0

The issue seems to be related to the fact that this.layout value is not different between the Dashboard, Users and Account settings.

I modified your code as follows:

 ngOnInit() {
    this.router.events.subscribe(data => {
      if (data instanceof RoutesRecognized) {
        this.layout = null;
        setTimeout(
          () => (this.layout = data.state.root.firstChild.data.layout)
        );
      }
    });
  }

Here the first thing is to reset the value of this.layout by setting to null. Allowing Angular to update itself. Then in a settimeout set the value to the one it needs to be again, which forces angular to reset the value and update itself.

As a side note, a possibly better approach would be to have shell routes and non shell routes rather than adjust the layout via the data property.

Steverob2k
  • 445
  • 8
  • 11