Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Routing child to parent is not working when navigates in Angular

I'm using angular 5.1.0, and I have an issue with the routing system, let me explain:

In my app-routing module I have an url /api that lazy loads another module, in that lazy loaded module I have the next routing implementation:

api-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: ApisComponent,
    data: {
      breadcrumbs: 'APIs',
    },
    children: [
      {
        path: '',
        component: ApiListComponent,
      },
      {
        path: ':id',
        component: ApiDetailComponent,
        resolve: {
          api: ApiResolverService
        },
        data: {
          breadcrumbs: '{{ api.title }}',
        },
      },
    ],
  },
];

The important thing here is the data param that the Router receives.

In my app I have a generic error behaviour that when an exception is throwed I have a errorHandler class that catch the error and redirects to another url: /error, this is the handler code:

import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { Router } from '@angular/router';

@Injectable()
export class AppErrorHandler implements ErrorHandler {

  constructor(private injector: Injector) { }

  handleError(error: any): void {
    const routerService = this.injector.get(Router);
    routerService.navigateByUrl('/error', { skipLocationChange: true });
  }
}

The problem is, when an exception is throwed inside /api and handleError is executed, I see my generic error page rendered with the breadcrumb loaded in the last route: /api by data param.

Is there any way to set the Router to reset data when is loaded? or maybe I'm doing something wrong?


UPDATE

At this point I thought the problem was due to data param, but now I see that it's not the problem. Let me show my error.component that is rendered when Router loads /error:

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-error',
  templateUrl: './error.component.html',
  styleUrls: ['./error.component.scss']
})
export class ErrorComponent implements OnInit {

  constructor(private router: Router, private route: ActivatedRoute) { }

  ngOnInit() {
    console.log('snapshot trace');
    console.log(this.route.snapshot);
  }
}

I have included in the onInit component method, a trace of ActivatedRoute snapshot to see what it has, and the thing is that trace is not showing when errorHandler navigates from /api to /error.

But if I load directly /error the trace is showed, so for any reason the error component is not instanciated correctly in the first scenario (navigate from /api to /error)


UPDATE I have upgraded to angular 5.2.9 and the problem still happens.

like image 310
Kalamarico Avatar asked Jan 18 '18 16:01

Kalamarico


People also ask

How to implement children component routing in parent route in angular?

Angular 8 Implementing Children Component Routing in Parent Component routes 1 Add Component for shop from following command: ng g c Shops 2 Add Component for Add Shops using following command: ng g c Shops/Add-Shop 3 Add Component for Update Shops using following command: ng g c Shops/Update-Shop More items...

When to choose between children and loadchildren in angular?

LoadChildren: It is also used to define nested routes, but Angular Router would lazily load them. You see the advantage here. Now that we have defined relevant Route properties, let's take a look at when we should choose between children and loadChildren. To add nested routes. Angular would load all child components upfront.

What is the use of children property in angular?

It is mainly used to identify the angular component that should be instantiated and loaded in the parent's router outlet. Component: This property refers to the angular component that should instantiate for this route. Children: This property defines nested routes, and angular would load them upfront.

What are nested routes in Angular 2?

Nested routes are routes within other routes. In this tutorial, we will show you how to create a child route and display the child components. The Angular allows us to nest child routes under another child routes effectively creating a Tree of routes. The Angular 2 applications are based on the idea of Components.


1 Answers

I have solved the problem using NgZone, I think the "timing" routing problem that angular has involve the render error component out of angular zone, so, the AppErrorHandler class looks like this:

import { ErrorHandler, Injectable, Injector, NgZone } from '@angular/core';
import { Router } from '@angular/router';

@Injectable()
export class AppErrorHandler implements ErrorHandler {

  constructor(private injector: Injector) { }

  handleError(error: any): void {
    const routerService = this.injector.get(Router);
    const ngZone = this.injector.get(NgZone);
    ngZone.run(() => {
      routerService.navigate(['/error'], { skipLocationChange: true });
    });
  }
}

Here a github issue related to my problem

like image 143
Kalamarico Avatar answered Oct 07 '22 02:10

Kalamarico