21

Getting this error when trying to use nestet route in Angular 4:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'component' of null
TypeError: Cannot read property 'component' of null
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseRoutes (http://localhost:4200/vendor.bundle.js:77976:71)
    at http://localhost:4200/vendor.bundle.js:77954:19
    at Array.forEach (native)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseChildRoutes (http://localhost:4200/vendor.bundle.js:77953:29)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.traverseRoutes (http://localhost:4200/vendor.bundle.js:77985:22)

This is my routing code:

const appRoutes: Routes = [
    {
        path: '',
        component: HomeComponent
    },

    {
        path: 'sobre',
        component: SobreComponent
    },
    {
        path: 'c/:concurso', component: ConcursoItemComponent

        , children: [         
            {

                path: ':cargo',
                component: CargoItemComponent,


                children: [
                    {
                        path: ':disc',
                        component: DisciplinaItemComponent,
                        children: [{
                            path: ':assunto',
                            component: AssuntoItemComponent
                        }]
                    }
                ]

            }
        ]
    },

];

I want to make the following nested rules, each one using the variables to inform the nested components of each route:

/

/c/:concurso/

/c/:concurso/:cargo/

/c/:concurso/:cargo/:disc/

/c/:concurso/:cargo/:disc/:assunto

On each level, I will need all the upper variables to make the correct querying of the related objects of the API.

Thanks for any help!

lmisael
  • 297
  • 1
  • 4
  • 13
  • Is it possible one of your components you are pulling into your routes file is incorrect? maybe it is being imported from the wrong path? – LLai Jun 27 '17 at 21:25
  • Well, I've checked the import paths and apparently they're all correct. The code compiles fine and run well until **/c/:concurso/**. The error happens in **/c/:concurso/:cargo/** I also took out all the DI in the component constructor and didn't help... Is my routing code correct? – lmisael Jun 27 '17 at 22:41
  • do you have a tag in your ConcursoItemComponent? – LLai Jun 27 '17 at 23:25
  • No, I have an outlet in the main app component. – lmisael Jun 28 '17 at 01:26
  • when some data coming from back end is null at that time when you assign to your model .the model object gets destroyed . – Madhu Nair Feb 28 '19 at 09:52

3 Answers3

27

As this article (https://angular-2-training-book.rangle.io/handout/routing/child_routes.html) states when dealing with child routes, just as you define a router-outlet for the root of your application, you must define a router-outlet for your parent component (in this case the ConcursoItemComponent. And technically also the CargoItemComponent & DisciplinaItemComponent) So you have 2 options.

  • Define a router-outlet in the ConcursoItemComponent. This way the router will know where to load the child component (CargoItemComponent) when the user visits c/:concurso/:cargo
  • Don't use child routes and instead make all of your routes at the top router level (root of the application)
{
    path: 'c/:concurso,
    component: ConcursoItemComponent
},
{
    path: 'c/:concurso/:cargo,
    component: CargoComponent
},
{
    path: 'c/:concurso/:cargo/:disc,
    component: DisciplinaItemComponent
},
{
    path: 'c/:concurso/:cargo/:disc/:assunto,
    component: AssuntoItemComponent
}

This way the router will always insert the component into the router-outlet at the root of the application.

Santhoshkumar
  • 780
  • 1
  • 16
  • 36
LLai
  • 13,128
  • 3
  • 41
  • 45
  • Thanks!! I've used the second option and it worked Just fine! Apparently the use of child routes is better suítes to when I would want nested portlets right? Which isnt the case here, I want the hierarchy to be displayed via breadcrumbs. – lmisael Jun 28 '17 at 12:15
  • I also had to add pathMatch:'full' in each route in order to make inner routes work. – lmisael Jun 28 '17 at 12:17
  • @lmisael Interesting that you need the pathMatch: 'full' to work. You are correct, you want child routes when you want to nest outlets. – LLai Jun 28 '17 at 12:59
  • Hi, I am facing the same issue with angular 5. I can't avoid children routes because of nested routes any other possible solution? – Hiral Sep 17 '18 at 03:59
  • @Imisael Can you please put your code? How can you define child routes for your cases? – Gokul Kumar Jan 28 '19 at 06:15
  • @Hiral I had the same issue such as yours. I did not want to change the Child routes to a flat-root-level structure. I found this solution while setting up ngx-breadcrumbs. Please check my answer here. It is too long to put it as a comment. – Manoj De Mel Feb 13 '19 at 22:33
4

Just thought I'd add a comment for the benefit of those who stumble across this for the same reason I did. If your template uses conditional rendering, and those conditions are satisfied asynchronously, the router-outlet cannot be inside the conditional markup because the framework might try to render the markup before the condition is satisfied. For example:

<div *ngIf="someAsyncCall()">
   <header>{{some result from the async call}}</header>
   <router-outlet></router-outlet>
</div>

may fail depending on how quickly the async call finishes. It's always safer to include only the static parts of a the markup in the conditional rendering. As in:

<div *ngIf="someAsyncCall()">
    <header>{{some result from the async call}}</header>
</div>
<router-outlet></router-outlet>

I got bit by wrapping the entire page in a "busy indicator" directive which pretty much guaranteed that the router-outlet would not be available all the time. Seems obvious in hindsight, but....

lje
  • 413
  • 5
  • 16
1

If anyone interested in going with Child route structure. You could follow this model. I found this in ngx-breadcrumbs.

const myRoutes : Route[] = {
  {
    path: '',
    component: HomeComponent        
  },
  {
    path: 'about',
    component: AboutComponent        
  },
  {
    path: 'person',
    children: [
      {
          path: '',
          component: PersonListComponent
      },
      {
          path: ':id',
          component: PersonDetailComponent              
      } 
    ]
  },    
  {
    path: 'folder',        
    children: [
      {
      path: '',
      component: FolderComponent
      },
      {
        path: ':id',
        component: FolderComponent            
      }
    ]
  }
};
Manoj De Mel
  • 927
  • 9
  • 16