4
votes

I am currently trying to implement an angular 2 application with multiple navigation levels. The problem is that my child components cannot find a router outlet when it is not explicitly declared in the parent component from my routes.

This is the error message i get:

Unhandled Promise rejection: Cannot find primary outlet to load 'EditUserComponent'

I want something like an edit or detail view which shows instead of the list view when i click on a button or link. The views are embedded in a template layout which has navigation structure and provides a router outlet for the content. I also want to target this router-outlet with all my views. I already tried using named outlets but without success. I use a breadcrumb component to show the current route, so i cannot make the edit/detail view to be a sibling of my list component.

To make it more clear, i made a plunker demo:

https://embed.plnkr.co/XXxADnS7q8FCfF4W84tS/

How can i solve the outlet issue and target the layout's router-outlet from child components?

1
Very nice that you added a plunkr, that helps a lot when trying to help out :)Fredrik Lundin

1 Answers

1
votes

One solution could be to simply wrap everything in your UsersComponent template, apart from the router outlet in a div. Then hide/show that div accordingly if the component has children (UsersEditComponentin this case) or not.

What this does is allowing your router to keep the correct parent/child hierarchy between UsersComponent and UsersEditComponent, while still ONLY showing the UsersEditComponent content when that route is activated.

This is an implementation of UsersComponent that does exactly that:

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

@Component({
  template: 
  `<div *ngIf="!hasChildren">
    User 1 <button md-icon-button (click)="editUser(1)">edit</button><br/>
    User 2 <button md-icon-button (click)="editUser(2)">edit</button>
  </div>
  <router-outlet></router-outlet>
  `
})

export class UsersComponent implements OnInit {
  private hasChildren: bool;
  constructor(private router: Router, private route:ActivatedRoute) { }

  editUser(id) {
    this.router.navigate(['users/edit', id]);
  }

  ngOnInit() {
    this.hasChildren = false;
    this.router.events.filter(event => event instanceof NavigationEnd).subscribe(event => {
      this.hasChildren = this.route.children.length > 0;
    }
  }
}