Angular 2 navigate to a different page on login

2019-09-15 18:44发布

问题:

I am developing a login page. On successful login, the user will be redirected to a different page. In the form, I have kept form attribute method="post" because I do not want the username and password to appear on the url. However, on successful login, when this.router.navigate(['post']); is executed, I am getting the error "cannot POST /post".

If I write method="get", things are working but the username and the password are appearing on the url. Please let me know what would be the correct approach to handle this:

login.component.ts

import { Component, trigger, state, style, transition, animate } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AuthenticatorService } from './authenticator.service';
import { Router } from '@angular/router';

@Component({
    selector: 'login',
    templateUrl: 'template/login.html',
    animations: [
        trigger('heroState', [
            state('inactive', style({
                height: '0',
                paddingTop: '0',
                paddingBottom: '0',
                marginTop: '0',
                marginBottom: '0',
                visibility: 'hidden',
                overflowY: 'hidden'
            })),
            state('active', style({

            })),
            transition('inactive => active', animate('300ms ease-in')),
            transition('active => inactive', animate('300ms ease-out'))
        ])

    ]
})
export class LoginComponent {

    private formGroup: FormGroup;
    private authenticated = false;
    private loginErrorMessage = 'inactive';
    constructor(formBuilder: FormBuilder, private authenticator: AuthenticatorService, private router: Router) {
        this.formGroup = formBuilder.group({
            username: ['', [Validators.required, Validators.minLength(3)]],
            password: ['', Validators.required]
        });
    }

    onClick() {
        this.authenticated = this.authenticator.authenticate(this.formGroup.controls["username"].value, this.formGroup.controls["password"].value);
        this.loginErrorMessage = this.authenticated?'inactive':'active';
        setTimeout(()=>{
            if(this.loginErrorMessage === 'active') {
                this.loginErrorMessage='inactive';
            }
        },3000);
        if(this.authenticated) {
            this.router.navigate(['post']);
        }
    }

    getLoginStatus() {
        return this.loginErrorMessage;
    }
}

form part of login.html

    <form [formGroup]="formGroup" role="form" action="" method="post" class="login-form">
        <div *ngIf="formGroup.controls.username.touched && formGroup.controls.username.errors && formGroup.controls.username.errors.required" class="error-text">Username is required</div>
        <div *ngIf="formGroup.controls.username.touched && formGroup.controls.username.errors && formGroup.controls.username.errors.minlength" class="error-text">Username must be atlease three characters long</div>
        <div class="form-group">
            <label class="sr-only" for="form-username">Username</label>
            <input formControlName="username" type="text" name="form-username" placeholder="Username..." class="form-username form-control" id="form-username">
        </div>
        <div class="form-group">
            <label class="sr-only" for="form-password">Password</label>
            <input formControlName="password" type="password" name="form-password" placeholder="Password..." class="form-password form-control" id="form-password">
        </div>
        <button [disabled]="!formGroup.valid" (click)="onClick()" type="submit" class="btn">Sign in!</button>
    </form>

回答1:

When you call this.router.navigate(['post']); , you are trying to tell the router to navigate to the URL hostname/post and load the corresponding component.

Either you have a component called post and this is a very bad practice since the name isn't really well chosen, or you are not understanding the correct use of the router.


To do what you want, you need to setup the submit() method on your login component so that you do an http.post() call and subscribe to the result to know if the authentication was successful or not; and then manage your router to load the component you want to get to after you have been successfully authenticated.

You should check out form submission and routing & navigation from the official documentation : https://angular.io/docs/ts/latest/guide/router.html#!#route-config



回答2:

The other answer in useful and helped me solve the problem. However, I am posting here the actual fix that solved the problem.

I had to remove the (click)="onClick()" on the submit button and add the (ngSubmit)="onClick()" to the form element.

The following text from the angular documentation helped in understanding:

The user should be able to submit this form after filling it in. The Submit button at the bottom of the form does nothing on its own but it will trigger a form submit because of its type (type="submit").

A "form submit" is useless at the moment. To make it useful, we'll update the tag with another Angular directive, NgSubmit, and bind it to the HeroFormComponent.submit() method with an event binding