Angular 8 lazy routes resolve with and without prefix and redirect before parent

Viewed 3086

I am trying to work with the router and lazy loading in angular 8. I have previously successfully used it in Angular 7.
I have a few basic routes which are as follows:

/home
/auth
/auth/login
/auth/signUp

I would like /auth to redirect to /auth/login and everything else to redirect to /home.
To accomplish this, my app-routing.module.ts looks like this:

const routes: Routes = [
  {
    path: '',
    redirectTo: '/home',
    pathMatch: 'full'
  },
  {
    path: 'auth',
    loadChildren: () => import('./modules/auth/auth.module').then(m => m.AuthModule)
  },
  {
    path: 'home',
    loadChildren: () => import('./modules/home/home.module').then(m => m.HomeModule)
  },
  {
    path: '**',
    redirectTo: '/home',
    pathMatch: 'full'
  }
];

And my auth-routing.module.ts looks like this:

const routes: Routes = [
  {
    path: '',
    redirectTo: '/auth/login',
    pathMatch: 'full'
  },
  {
    path: 'login',
    component: LoginComponent
  },
  {
    path: 'signUp',
    component: LogoutComponent
  }
];

The problem is that it always redirects to the auth page and ignores the other redirects. The /login and /signUp paths are also available at a root level, which is odd, but they also work when prefixed with /auth/login which is even more peculiar.

So for some reason the routes seem to exist twice.
Also when I prefix the paths in auth-routing.module.ts with auth/ it is suddenly possible to direct to /auth/auth/login

I have activated all necessary features of Angular 8 to make ivy and lazy loading work. The other routes and lazy modules I have defined are working.

2 Answers

You need to use relative redirects like this:

app-routing.module.ts

import {NgModule} from '@angular/core';
import {Route, RouterModule} from '@angular/router';
const routes: Route[] = [
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full'
  },
  {
    path: 'auth',
    loadChildren: () => import('./modules/auth/auth.module').then(m => m.AuthModule)
  },
  {
    path: 'home',
    loadChildren: () => import('./modules/home/home.module').then(m => m.HomeModule)
  },
  {
    path: '**',
    redirectTo: 'home',
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

auth-routing.module.ts

import {NgModule} from '@angular/core';
import {Route, RouterModule} from '@angular/router';
import { LoginComponent } from './login.component';

import { LogoutComponent } from './logout.component';
const routes: Route[] = [
  {
    path: '',
    redirectTo: 'login',
    pathMatch: 'full'
  },
  {
    path: 'login',
    component: LoginComponent
  },
  {
    path: 'signUp',
    component: LogoutComponent
  }
];

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

home-routing.module.ts

import {NgModule} from '@angular/core';
import {Route, RouterModule} from '@angular/router';
import { HomeComponent } from './home.component';
const routes: Route[] = [
  {
    path: '',
    component: HomeComponent
  }
];

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

See https://stackblitz.com/edit/angular-gmsgn2 for a working example.

Make sure that You have import AuthModule, and HomeModule only in app-routing.module.ts (as lazy loading). Check that those modules aren't imported inside app.module.ts as normal (no lazy loading) way.

Related