Search code examples
angulartypescriptangular2-routingangular2-router3

Angular 2 Routes not working while navigating through browser URL


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.


Solution

  • 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