¿Cómo puedo establecer manualmente un campo de formulario de Angular como inválido?

Estoy trabajando en un formulario de inicio de sesión y si el usuario introduce credenciales no válidas, queremos marcar los campos de correo electrónico y contraseña como no válidos y mostrar un mensaje que diga que el inicio de sesión ha fallado. Cómo puedo hacer para que estos campos sean inválidos desde un callback observable?

Idioma: lang-html -->

Plantilla:

<form #loginForm="ngForm" (ngSubmit)="login(loginForm)" id="loginForm">
  <div class="login-content" fxLayout="column" fxLayoutAlign="start stretch">
    <md-input-container>
      <input mdInput placeholder="Email" type="email" name="email" required [(ngModel)]="email">
    </md-input-container>
    <md-input-container>
      <input mdInput placeholder="Password" type="password" name="password" required [(ngModel)]="password">
    </md-input-container>
    <p class='error' *ngIf='loginFailed'>The email address or password is invalid.</p>
    <div class="extra-options" fxLayout="row" fxLayoutAlign="space-between center">
     <md-checkbox class="remember-me">Remember Me</md-checkbox>
      <a class="forgot-password" routerLink='/forgot-password'>Forgot Password?</a>
    </div>
    <button class="login-button" md-raised-button [disabled]="!loginForm.valid">SIGN IN</button>
     <p class="note">Don't have an account?<br/> <a [routerLink]="['/register']">Click here to create one</a></p>
   </div>
 </form>

Método de inicio de sesión:

idioma: lang-ts -->

 @ViewChild('loginForm') loginForm: HTMLFormElement;

 private login(formData: any): void {
    this.authService.login(formData).subscribe(res => {
      alert(`Congrats, you have logged in. We don't have anywhere to send you right now though, but congrats regardless!`);
    }, error => {
      this.loginFailed = true; // This displays the error message, I don't really like this, but that's another issue.
      this.loginForm.controls.email.invalid = true;
      this.loginForm.controls.password.invalid = true; 
    });
  }

Además de poner el indicador de invalidez de las entradas en true, he probado a poner el indicador email.valid en false, y a poner el indicador loginForm.invalid en true también. Ninguno de ellos hace que las entradas muestren su estado inválido.

Solución

en el componente:

formData.form.controls['email'].setErrors({'incorrect': true});

y en HTML:

<input mdInput placeholder="Email" type="email" name="email" required [(ngModel)]="email"  #email="ngModel">
<div *ngIf="!email.valid">{{email.errors| json}}</div>
Comentarios (11)

Añadir a la respuesta de Julia Passynkova's

Para establecer el error de validación en el componente:

formData.form.controls['email'].setErrors({'incorrect': true});

Para desajustar el error de validación en el componente:

formData.form.controls['email'].setErrors(null);

Tenga cuidado con la anulación de los errores utilizando null ya que esto sobrescribirá todos los errores. Si quiere mantener algunos, puede que tenga que comprobar primero la existencia de otros errores:

if (isIncorrectOnlyError){
   formData.form.controls['email'].setErrors(null);
}
Comentarios (3)

En la nueva versión del material 2 cuyo nombre de control comienza con el prefijo mat setErrors() no funciona, en su lugar se puede cambiar la respuesta de Juila's:

formData.form.controls['email'].markAsTouched();
Comentarios (0)