Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught (in promise): TypeError: Cannot read property 'component' of null

Tags:

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!

like image 713
lmisael Avatar asked Jun 27 '17 21:06

lmisael


2 Answers

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.

like image 69
LLai Avatar answered Oct 21 '22 04:10

LLai


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....

like image 31
lje Avatar answered Oct 21 '22 03:10

lje