Angular 2 Routes not working while navigating through browser URL

All Іѕ Vаиітy picture All Іѕ Vаиітy · Mar 15, 2017 · Viewed 12.6k times · Source

I have some problems with routes for an Angular project, mainly with the third level of child routes. The routes are working prefectly while navigating on the app. (routerLink) and the problem arise when accessing the URL through the browser URL.

My Angular version is 2.4.0
I am testing on dev server with ng serve.

For a project with the given structure,

.
├── photos
├── posts
├── users
│   ├── detail
│   │   ├── address
│   │   ├── family
│   │   ├── information
│   │   └── phones
│   ├── friends
│   └── profile
└── videos

The following is the code,

// user routes
export const userRoutes : Routes = [
  {
    path: 'detail',
    component: DetailComponent
  },
  {
    path: 'friends',
    component: FriendsComponent
  },
  {
    path: 'profile',
    component: ProfileComponent
  }
]

//app routes
const appRoutes: Routes = [
  {
    path: '',
    component: HomeComponent
  },
  {
    path: 'photos',
    component: PhotosComponent
  },
  {
    path: 'posts',
    component: PostsComponent
  },
  {
    path: 'users',
    component: UserListComponent
  },
  {
    path: 'user/:username',
    component: UserComponent,
    children: userRoutes
  },
  {
    path: 'videos',
    component: VideosComponent
  }
]
export const AppRoutes = RouterModule.forRoot(appRoutes);
export const appRoutingProviders: any[] = [];

and is registered as,

@NgModule({
  declarations: [
    // declarations
  ],
  imports: [
    AppRoutes
  ],
  providers: [
    appRoutingProviders
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

So the Application works well with the RouterLink

[routerLink]="['/user', username, 'detail']

but when I navigate the browser <host>/user/myuser/detail it raise exception

Uncaught (in promise): Error: Cannot find primary outlet to load 'DetailComponent'

Whats wrong? Thanks.

NB: I have setup <router-outlet> and is working perfectly on routerLink and the problem arises when the navigate through full url in browser.

Answer

YounesM picture YounesM · Mar 17, 2017

I'm supposing that when you're navigating from user/:username/ to /user/:username/detail you need your UserComponent to hide everything that's on his template and show the DetailComponent

So to achieve that you'll need a component that will load its children component :

parent.component.html

<router-outlet></router-outlet>

routes.ts

Now let's set the routes so that user/:username/ will load in the parent component

// user routes
export const userRoutes : Routes = [
 {
    path: '',
    component: UserComponent // the '' path will load UserComponent
  },
  {
    path: 'detail',
    component: DetailComponent
  },
  {
    path: 'friends',
    component: FriendsComponent
  },
  {
    path: 'profile',
    component: ProfileComponent
  }
]

//app routes
const appRoutes: Routes = [
  {
    path: '',
    component: HomeComponent
  },
  {
    path: 'photos',
    component: PhotosComponent
  },
  {
    path: 'posts',
    component: PostsComponent
  },
  {
    path: 'users',
    component: UserListComponent
  },
  {
    path: 'user/:username',
    component: ParentComponent, //This component will load its children
    children: userRoutes
  },
  {
    path: 'videos',
    component: VideosComponent
  }
]
export const AppRoutes = RouterModule.forRoot(appRoutes);
export const appRoutingProviders: any[] = [];

So, what is happening here is that when you navigate to user/:username ParentComponent is loaded then UserComponentloaded in parent component's outlet (since the '' path correspond to user/:username)

Here is a working example : Github

When you access user/myuserit will display : user works ! user/myuser/details will display : details works ! as you can see below (Without using a routerlink)

enter image description here