Ismail
Ismail

Reputation: 1316

Angular: Can not navigate to child components inside a module

I have a Project Dashboard within which there are 2 sub apps.

├───projects
│   ├───app1
│   │   ├───e2e
│   │   │   └───src
│   │   └───src
│   │       ├───app
│   │       │   ├───form
│   │       │   ├───home
│   │       │   └───page-not-found
│   │       ├───assets
│   │       └───environments
│   ├───app2
│   │   ├───e2e
│   │   │   └───src
│   │   └───src
│   │       ├───app
│   │       │   ├───core
│   │       │   ├───home
│   │       │   ├───mail-view
│   │       │   ├───mailbox
│   │       │   ├───models
│   │       │   ├───page-not-found
│   │       │   └───service
│   │       ├───assets
│   │       └───environments
│   └───app3
│       ├───e2e
│       │   └───src
│       └───src
│           ├───app
│           ├───assets
│           └───environments
├───resources
└───src
    ├───app
    │   ├───components
    │   │   ├───navigation
    │   │   └───progressbar
    │   ├───core
    │   │   ├───authentication
    │   │   └───service
    │   ├───dashboard
    │   │   ├───models
    │   │   ├───service
    │   │   └───widget
    │   ├───login
    │   └───shared
    │       ├───common
    │       │   ├───config
    │       │   └───service
    │       └───core
    ├───assets
    └───environments

Navigation to app1 and app2 from dashboard-app is working as expected.
In app2 mail-view, mailbox are child components of home component.

const routes: Routes = [
  { path: 'mail', redirectTo: 'mail/home', pathMatch: 'full' },
  { path: 'mail/home', pathMatch: 'full', component: HomeComponent,
    children: [
      { path: '', pathMatch: 'full', component: LoaderComponent },
      { path: 'mailbox/:type', component: MailboxComponent ,  resolve: { response: MailboxResolverService }},
      { path: 'mailbox/BLK/list/:header', pathMatch: 'full', component: BulkMailListComponent },
      { path: 'viewMail/:type/:mailId', pathMatch: 'full', component: MailViewComponent }
    ]
  /*canActivate: [AuthGuard]*/ },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})

When I try to navigate to any of the child components I get Error 'Path not Found'.

this.route.navigate(['./mailbox/', AppConstants.MAILBOX_TYPE.INBOX_I], {relativeTo: this.aRoute}); 
custom-error-handler.service.ts:25 Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'mail/home/mailbox/INBI'
Error: Cannot match any routes. URL Segment: 'mail/home/mailbox/INBI'
    at ApplyRedirects.push../node_modules/@angular/router/fesm5/router.js.ApplyRedirects.noMatchError (router.js:2459)
    at CatchSubscriber.selector (router.js:2440)
  1. Is there a particular way to declare children when using sub modules
  2. Or is the navigation is to be done in different way.

Thanks in advance.

Upvotes: 2

Views: 1495

Answers (3)

Ismail
Ismail

Reputation: 1316

After few trail and error, I was able to find he culprit pathMatch: 'full' was causing the issue. After changing the parent routing param from
path: 'mail/home', pathMatch: 'full', component: HomeComponent
to
path: 'mail/home', component: HomeComponent
issue got resolved. According to Angular -

The path-matching strategy, one of 'prefix' or 'full'. Default is 'prefix'.

By default, the router checks URL elements from the left to see if the URL matches a given path, and stops when there is a match. For example, '/team/11/user' matches 'team/:id'.

The path-match strategy 'full' matches against the entire URL. It is important to do this when redirecting empty-path routes. Otherwise, because an empty path is a prefix of any URL, the router would apply the redirect even when navigating to the redirect destination, creating an endless loop.

It seems that when pathmatch: 'full' is given the angular router, after getting the first hit from parent will not look into its children. In the default case pathMatch: 'prefix' even after getting the first hit, angular will look into the child components for remaining url match.
This 3 minute Video explains it well - https://www.youtube.com/watch?v=St2Gywjlwks

Upvotes: 1

Muhammed Faizan
Muhammed Faizan

Reputation: 24

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
You don't need to import like this just simple call your child component 
in view 
<ul>
<li>
  your parent
  <ul>
     <li> your child </li>
  </ul>
</li>
<ul>

Upvotes: 0

Padmapriya Vishnuvardhan
Padmapriya Vishnuvardhan

Reputation: 2166

./mailbox/ is a problem.

It should be like below.

this.route.navigate(['mailbox/', AppConstants.MAILBOX_TYPE.INBOX_I], {relativeTo: this.aRoute});

Upvotes: 0

Related Questions