troglodytto
troglodytto

Reputation: 121

Conditionally rendering different components on same route (Angular)

I have 2 Separate Views, One For Homepage and Another for Authentication; I want to render LoginComponent on route '/' and SignupComponent on route '/signup' If user is NOT Logged in otherwise render components of Homepage. I have tried having 2 Different Router Outlets for Homepage and Auth (But that Shows that the route '/signup' is not configured). Here is My Code

<div *ngIf="logged$ | async; else login">
  <app-header></app-header>
  <router-outlet></router-outlet>
  <!-- ? Primary Outlet -->
</div>
<ng-template #login>
  <router-outlet name="auth"></router-outlet>
  <!-- ? Secondary Outlet for Auth  -->
</ng-template>

@Component({ ... })
export class AppComponent {
  logged$: Observable<boolean>;

  constructor(private store: Store<State>) {
    this.logged$ = store.select('logged');
  }
}

const routes: Routes = [
  { path: '', children: [/* Homepage Components */] },
  {
    path: '',
    children: [
      { path: '', component: LoginComponent },
      { path: 'signup', component: SignupComponent },
    ],
    outlet: 'auth',
  },
];

@NgModule({ ... })
export class AppRoutingModule {}

Upvotes: 1

Views: 3003

Answers (1)

Bojan Kogoj
Bojan Kogoj

Reputation: 5649

Instead of displaying two pages on same URL create a guard. Guard will be called before going to URL, and in this example will redirect you to login if you don't have a token (here we're assuming you have a AuthService with hasAuthToken method)

@Injectable({
  providedIn: 'root',
})
export class AuthGuard implements CanActivate {

  constructor(
    private router: Router,
    private auth: AuthService
  ) { }

  canActivate(): boolean {
    if (this.auth.hasAuthToken()) {
      return true;
    }
    this.router.navigate(['/login']);
    return false;
  }

Routing:

const routes: Routes = [
  { 
    path: '',
    children: [/* Homepage Components */],
    canActivate: [AuthGuard] // Added here
  },
  {
    path: '',
    children: [
      { path: '', component: LoginComponent },
      { path: 'signup', component: SignupComponent },
    ],
    outlet: 'auth',
  },
];

@NgModule({ ... })
export class AppRoutingModule {}

Upvotes: 1

Related Questions