All Іѕ Vаиітy
All Іѕ Vаиітy

Reputation: 26422

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.

Upvotes: 4

Views: 13843

Answers (4)

user3522814
user3522814

Reputation: 1

use <base href="/"> inside into tag. Note <base href="/"> it should be top inside head tag.

<head>
  <base href="/">
 other css and jquery ...
</head>

Routing like

const appRoutes: Routes = [
    {
        path: 'Admin',
        component: AdminComponent,
        children: [

            {
                path: 'CandidateInfo',
                component: CandidateInfoComponent
            },
            {
                path: 'RptCandidateInfo',
                component: RptCandidateInfoComponent
            },
            {
                path: 'RptCandidateInfoDT',
                component: RptCandidateDTInfoComponent
            }
        ]
    },
];

Its working fine.

Upvotes: 0

YounesM
YounesM

Reputation: 2317

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

Upvotes: 8

Andrej Kikelj
Andrej Kikelj

Reputation: 800

Have you set the <base href="/">?

What is your backend? In case a user first navigates to a full URL of the subpage of your application(e.g. www.mysite.com/users/john-doe) and your backend does not return the angular 2 bootstrapped page(index.html with the bootstrap scripts), then the angular router will never kick in, although I think this is not the issue in your case, since you are getting an error from angular.

I have my .net core backend set to always return index.html for requests that are not static files, so it always properly loads the app and uses the angular routing.

Upvotes: 0

Lalit Dogra
Lalit Dogra

Reputation: 11

Use this code in html routerLink="/user" and please mention your path in routing.ts and when u click this routerlink it will jump to concerned link

Upvotes: -3

Related Questions