Angular2 Router: Error: Cannot find primary outlet to load 'InboxComponent'

16,355

Solution 1

Your MailListComponent needs a <router-outlet> as well, because InboxComponent is defined as a child in your router configuration:

@Component({
  selector: 'app-mail-list',
  template: `
    <p>
      Mail list works!
    </p>
    <router-outlet></router-outlet>
  `,
  styleUrls: ['./mail-list.component.css']
})
export class MailListComponent {

  constructor() { }

}

If you however want to render the InboxComponent inside the same outlet, you should not add it as a child

Solution 2

Another way if you want to avoid adding a <router-outlet></router-outlet> is to change the way you define your routes into the following:

const routes = [
  { path: '',
    children: [
      {
        path: '',
        component: MailListComponent
      }
    ]
  },
  { path: 'mail', 
    children: [
      {
        path: '',
        component: MailListComponent
      },
      {
        path: 'inbox', 
        component: InboxComponent
      }
    ]
  }
];

This will allow you to use the same <router-outlet></router-outlet> as above to host the new component

Share:
16,355
Zurab
Author by

Zurab

Javascript developer (Vue.js), Oracle PL/SQL developer I have experience in using vanilla javascript, Vue framework, some HTML/CSS experience. Extensive experience with Oracle SQL and PL/SQL. Ideal work would combine JS code development and PL/SQL code development.

Updated on June 24, 2022

Comments

  • Zurab
    Zurab almost 2 years

    I created a simple app with routing. Links "http:// localhost:4200" and "http:// localhost:4200/mail" work well,

    but when I try to open a link "http:// localhost:4200/mail/inbox" I get an error: "Cannot find primary outlet to load 'InboxComponent'".

    What causes the error and how can I fix it?

    Here are my *.ts files:

    app.module.ts :

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { HttpModule } from '@angular/http';
    import { RouterModule } from '@angular/router';
    
    import { AppComponent } from './app.component';
    import { MailListComponent } from './components/mail-list/mail-list.component';
    import { FoldersComponent } from './components/folders/folders.component';
    import { InboxComponent } from './components/inbox/inbox.component';
    
    const routes = [
      { path: '',
        component: MailListComponent
       },
    
      { path: 'mail', component: MailListComponent,
          children: [
            {path: 'inbox', component: InboxComponent}
          ]
      }
    ];
    
    @NgModule({
      declarations: [
        AppComponent,
        MailListComponent,
        FoldersComponent,
        InboxComponent
      ],
      imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        RouterModule.forRoot(routes)
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    app.component.ts :

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      template: `
        <app-folders></app-folders>
        <router-outlet></router-outlet>
      `,
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      title = 'app works!';
    }
    

    folders.component.ts :

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-folders',
      template: `
        <aside class="folders">
          <ul>
            <li><a routerLink="mail/inbox">Inbox</a></li>
          </ul>
        </aside>
      `,
      styleUrls: ['./folders.component.css']
    })
    export class FoldersComponent {
      folders: any[];
    
      constructor() { }
    
    }
    

    mail-list.component.ts :

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-mail-list',
      template: `
        <p>
          Mail list works!
        </p>
      `,
      styleUrls: ['./mail-list.component.css']
    })
    export class MailListComponent {
    
      constructor() { }
    
    }
    

    inbox.component.ts :

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-inbox',
      template: `
        <p>
          inbox works!
        </p>
      `,
      styleUrls: ['./inbox.component.css']
    })
    export class InboxComponent implements OnInit {
    
      constructor() { }
    
      ngOnInit() {
      }
    
    }
    
  • Ivan Yurchenko
    Ivan Yurchenko about 7 years
    Thank you very much! It's the only answer out of many that really helped me. However, I have no idea how Angular determines that the component is a child (I don't have a child route like the author and still Angular thinks for some reason that it's a child component). Any ideas where can I find a configuration of this relationship?
  • Poul Kruijt
    Poul Kruijt almost 7 years
    You do have a child route, because inbox is inside the children array of mail :)