Angular 7 routerLink directive warning 'Navigation triggered outside Angular zone'

Veetaha picture Veetaha · Nov 3, 2018 · Viewed 17.5k times · Source

I am struggling with Angular framework to get my application run smoothly, but I can't resolve an issue with routing. I have a top level AppComponent and app-routing.module.ts which manage the navigation via my custom SlideMenuComponent. My simplified html template of AppComponent:

<app-slide-menu [buttons]="menuButtons"></app-slide-menu>
<router-outlet></router-outlet>

My SlideMenuComponent has the following html as its core:

<nav><div *ngFor="let button of buttons">
    <a routerLink="{{button.routerLink}}"
    >{{button.name}}</a>
</div></nav>

A user can navigate to '/courses' through this slide menu, which is supervised by CoursesComponent that paginates links to a particular CourseComponents that are retrieved from the server. These components reside in their own courses.module.ts module whith their own courses-routing.module.ts. But when I click any of those links I get Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'? console warning, ngOnInit() is not called for openned CourseCompontent, and it doesn't update untill I click any of the buttons on the page. I had this issue when manually navigating via router.navigate() that was resolved by forwarding this task to NgZone.runTask(router.navigate()), but why does this happen with anchor tags and routerLink direcrives? Here is my CoursesComponent code excerpt:

<nav><ul>
        <li *ngFor="let course of api.data | paginate: {
            currentPage: currentPage, itemsPerPage: limit, totalItems: api.total
        }">
           <a
               [routerLink]="course._id"
               [queryParams]="{ page: '1', limit: '5' }"
           >
            {{course.name}} ({{course.description}})
           </a>
        </li>
</ul></nav>

A gif to demonstrate the issue:

enter image description here

Answer

calebeaires picture calebeaires · Nov 8, 2018

It seens a bug, try this as an workaround

constructor(private ngZone: NgZone, private router: Router) {}

public navigate(commands: any[]): void {
    this.ngZone.run(() => this.router.navigate(commands)).then();
}