Abrar Hossain
Abrar Hossain

Reputation: 2702

Angular Routing: Not able to make redirect

This may be a very common angular routing problem but, I cannot seem to make it work. I am not sure whether I understand all the concepts clearly even after going through the angular docs. Here's what I want to achieve and what I have tried:

I have a login application. When the user clicks proceed in the login form, I want the application to redirect to a new page/app. To do this:

  1. I first tried adding a RouterModule to my @NgModule imports list in app.module.ts file.

import { RouterModule, Routes } from '@angular/router';

// Routes
const routes: Routes = [
  {path: "", component: InvestigatorLoginComponent},
  {path: 'invdashboard', component: InvDashboardComponent}
];
//...
@NgModule({
// ...
imports: [
// ...
RouterModule.forRoot(
  routes, { enableTracing: true} // <= debugging
),
// ...
})
export class AppModule {}
  1. Added <router-outlet></router-outlet> to <inv-dashboard> component:

app.component.html

<div id='login-app-wrapper'>
  <nav-top></nav-top>
  <investigator-login></investigator-login> 
</div>

inv-dashboard.component.html

<router-outlet></router-outlet>
<p>
  inv-dashboard works!
</p>

inv-dashboard.component.ts

import { RouterOutlet } from '@angular/router'; 

@Component({
  selector: 'inv-dashboard',
  templateUrl: './inv-dashboard.component.html',
  styleUrls: ['./inv-dashboard.component.css']
})
export class InvDashboardComponent implements OnInit { // ... }
  1. Login component: investigator-login.component.html

     <form class='inv-login' [formGroup]="invLoginForm" (ngSubmit)="onSubmit(invLoginForm.value)">
    
     <mat-form-field class='inv-login-full-width-input'>
    
     <input matInput placeholder="Username" formControlName="fcUsername" value="" maxlength="30">
     </mat-form-field>
    
     <mat-form-field class='inv-login-full-width-input'>
     <input matInput placeholder="Password" formControlName="fcPassword" value="" maxlength="25">  
     </mat-form-field>
     <div class='prcd-btn-container'>
        <button mat-button color='primary' type='submit'>Proceed</button>
     </div>
    </form>
    

investigator-login.component.ts

`onSubmit(f: any): void {
    this.authenticator.postContent(f)
      .subscribe(
        this.handleLoginResponse,
        err => { throw new Error('failed'); } 
      );
  }
  handleLoginResponse(res: IResponseSuccess) {
    if(res.status === 200) {
      // success 
      console.log(res.template);
    }
    else {
      console.error('Server error ' + res.status);
    }
  }`

When after filling out the form, I click proceed, nothing happens. The stack track shows no redirection. Do I need to add any redirection code to the proceed button handler in the form? I am really not sure what else to add.

Thanks

Upvotes: 0

Views: 934

Answers (2)

Abrar Hossain
Abrar Hossain

Reputation: 2702

Taking the suggestion from @YousefKhan I tried the solution he posted. It solved my initial problem. Initially, the problem was in how I defined my routes and how I set the app.component.html file which, should only host a <router-outlet></router-outlet> component. I have moved all other templates from app.component.html to relevant components and, added the Routes in my app.module.ts So, after making the changes:

app.module.ts Router

// Routes
const routes: Routes = [
  {path: "", redirectTo: "login", pathMatch: "full"},
  {path: "login", component: InvestigatorLoginComponent},
  {path: "dashboard", component: InvDashboardComponent}
];

app.component.html

<router-outlet></router-outlet>

This resolved the issue of routing and, helped me understand the concept better. For reference, check out this article on angular routing here.

The other problem I faced, as I mentioned in the comment was that the this context inside the subscribe handler was not bound to the InvestigatorLoginComponent instance. Easy solution would be use an arrow function. However, since I wanted to keep my handler separate, I used bind to add this context to the handler.

investigator-login.component.ts

onSubmit(f: any): void {
this.authenticator.postContent(f)
  .subscribe(
    this.handleLoginResponse.bind(this),
    err => { throw new Error('failed'); } 
  );

}

Hope it helps.

Upvotes: 0

Yousef khan
Yousef khan

Reputation: 3204

You are not navigating anywhere on success. Inject Router in the constructor like:

constructor(private router: Router) { }

and then navigate on success

handleLoginResponse(res: IResponseSuccess) {
    if(res.status === 200) {
      // success 
      console.log(res.template);
      this.router.navigate(['/invdashboard']);
    }
    else {
      console.error('Server error ' + res.status);
    }
  }

Upvotes: 1

Related Questions