2

I have spent several hours trying to show an error when a form submits and returns an error status code. I can't seem to figure this out...

Login form component in the comments below i showed where id like to tell the form that it is invalid or valid.

import { Component, OnInit, Input, Output, EventEmitter  } from '@angular/core';
import { Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators, NgForm } from "@angular/forms";
import { AuthenticationService } from "../../../services/authentication.service";
import { User } from "../../../domain/user";


@Component({
  selector: 'login-form',
  templateUrl: './login-form.component.html'
})
export class LoginFormComponent implements OnInit {

  loginForm: FormGroup;
  post: any;
  username: string;
  password: string;
  user: User;
  errorMessage: string  = '';


  constructor(private fb: FormBuilder, private router: Router, private authenticationService: AuthenticationService) {
    this.loginForm = fb.group({
      'username': [null, Validators.required],
      'password': [null, Validators.required],
      'login': false
    });
  }


  ngOnInit() {
    this.authenticationService.logout(); // reset login status
  }


  login(values) {
    this.username = values.username;
    this.password = values.password;

    this.authenticationService.login(this.username, this.password)
      .subscribe(result => {
          if (result === true) {
            this.router.navigate(['/']);
            localStorage.setItem('currentUser', JSON.stringify(this.user));
            // here form should be valid
          } else {
            this.errorMessage = 'Username or password is incorrect';
            // here form should be invalid
          }
      });
  }
}

Login Form Html, the second <div> is the error id like shown after the form submits.

<form id="loginForm" [formGroup]="loginForm" (ngSubmit)="login(loginForm.value)" novalidate>
  <div class='form-text error' *ngIf="submitted">
    <div *ngIf="loginForm.invalid" class="help-block error small">Username or password is incorrect.</div>
  </div>
  <div class="form-group">
    <label class="control-label" for="username">Username</label>
    <input type="text" placeholder="Please enter your usename" title="Please enter you username" required value=""
           id="username" class="form-control" name="username" formControlName="username">
    <div class='form-text error' *ngIf="loginForm.controls.username.touched">
      <div *ngIf="loginForm.controls.username.hasError('required')" class="help-block error small">Username is required.</div>
    </div>
    <span *ngIf="loginForm.controls.username.valid || !loginForm.controls.username.touched"  class="help-block small">Your unique username</span>
  </div>
  <div class="form-group">
    <label class="control-label" for="password">Password</label>
    <input type="password" title="Please enter your password" placeholder="******" required value=""
           id="password" class="form-control" name="password" formControlName="password">
    <div class='form-text error' *ngIf="loginForm.controls.password.touched">
      <div *ngIf="loginForm.controls.password.hasError('required')" class="help-block error small">Password is required.</div>
    </div>
    <span *ngIf="loginForm.controls.password.valid || !loginForm.controls.password.touched" class="help-block small">Your strong password</span>
  </div>
  <div>
    <button type="submit" class="btn btn-accent" [disabled]="!loginForm.valid">Login</button>
    <a class="btn btn-default" routerLink="/register">Register</a>
  </div>
</form>
1

2 Answers 2

4

It is error from server side, your form is valid here. So, set flag to false in your failure handler.

Component:

Make a variable for it first:

export class LoginFormComponent implements OnInit {

  loginForm: FormGroup;
  post: any;
  username: string;
  password: string;
  user: User;
  errorMessage: string  = '';
  authenticationFlag: boolean = true;

and in your login method:

login(values) {
    this.username = values.username;
    this.password = values.password;

    this.authenticationService.login(this.username, this.password)
      .subscribe(result => {
          if (result === true) {
            this.router.navigate(['/']);
            localStorage.setItem('currentUser', JSON.stringify(this.user));
            // here form should be valid
          } else {
             this.authenticationFlag = false;
          }
      });
  }

HTML Template:

Change this code:

<div class='form-text error' *ngIf="submitted">
    <div *ngIf="loginForm.invalid" class="help-block error small">Username or password is incorrect.</div>
</div>

By this:

<div *ngIf="!authenticationFlag" class="help-block error small">Username or password is incorrect.</div>
Sign up to request clarification or add additional context in comments.

1 Comment

Thank You, So i tried this twice and it didn't work. But it helped me to realize that my error handling was wrong. Please see my answer below, accepting this one since it helped me realize my mistake.
1

So within my authentication service class I wasn't handling the errors properly. I changed my login method within the authentication service to include a catch.

  login(username: string, password: string): Observable<boolean> {
    let user = JSON.stringify({ username: username, password: password });
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    return this.http.post(this.loginUrl, user, options)
      .map(function(res){
        let data = res.json();
        alert(res.status);

        if (data) {
          this.token = data.token;
          localStorage.setItem('currentUser', JSON.stringify({ username: username, token: this.token }));
          return true; // successful login
        } else {
          return false; // failed login
        }
      })
      .catch((error:any) => Observable.throw(error.json().error || 'Server error'));
  }

Then within my login form component I changed the use of the auth service login method to:

  login(values) {
    this.username = values.username;
    this.password = values.password;

    this.authenticationService.login(this.username, this.password)
      .subscribe(result => {
          if (result === true) {
            this.router.navigate(['/']);
            localStorage.setItem('currentUser', JSON.stringify(this.user));
          }
      },
      err => {
        this.authenticationFlag = false;
      });
  }

as @Wasif Khan put in his answer all I needed was a component variable. This was too long for a comment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.