Custom validation [Solved]


#1

Hi, friends!
How to validate from a database service? its not working:

UsuarioValidator.ts

import { FormControl } from '@angular/forms';
import { VentasServicio } from "../providers/ventas-servicio";

export class UsuarioValidator {

    static isUsuario(control: FormControl): any {
        return new Promise(resolve => {
            let db: VentasServicio;
            db.getUsuario(control.value).then((data) => {
                if (data === null) {
                    resolve(null);
                } else {
                    resolve({ "is_usuario": true });
                }
            })
                .catch(error => {
                    console.log('ERROR ' + error);
                });
        });
    }

}

RegistroPage.ts

constructor(public navCtrl: NavController, public navParams: NavParams,
    public alertCtrl: AlertController, public formBuilder: FormBuilder, public db: VentasServicio) {
    this.registroFrm = this.formBuilder.group({
      'usuario': ['', Validators.required, UsuarioValidator.isUsuario],
      'clave': ['', Validators.required],
      'email': ['', Validators.required],
      'usuarioInventiva': ['', Validators.required]
    });
  }

RegistroPage.html

      <ion-item>
        <ion-label stacked>Usuario</ion-label>
        <ion-input formControlName="usuario" type='text' autocapitalize="off"></ion-input>
      </ion-item>
      <ion-item *ngIf="registroFrm.get('usuario').pending">
        <p>Verificando usuario...</p>
      </ion-item>
      <ion-item *ngIf="registroFrm.get('usuario').errors && registroFrm.get('usuario').dirty">
        <p *ngIf="registroFrm.get('usuario').hasError('required')" color="danger">Campo requerido</p>
        <p *ngIf="registroFrm.get('usuario').hasError('is_usuario')" color="danger">Usuario ya existe</p>
      </ion-item>

Thanks!


#2

A couple of things:

  • Don’t create needless promises. getUsario() is presumably giving you one, simply chain off that. Do not make a new one.

  • DI is smart, but not smart enough to do anything with let db: VentasServicio;. db is going to be null and I suspect this is the source of your problems. Instead use a lambda like so:

class SomePage {
  registroForm: FormGroup;

  constructor(fb: FormBuilder, db: VentasServicio) {
    let isUsario = (control: FormControl) => {
      // in here, `db` is magically reliable
      return db.getUsario(control.value).then(data => data ? {} : {"is_usario": true});
    };

   this.regsitroForm = fb.group({
      'usuario': ['', Validators.required, isUsario],
    });
  }
}

If you insist on breaking it out into a separate class from the page (for reusability reasons, for example), look into how to provide deps to custom providers (any unit testing Http services example will have an example of doing this to mock HttpBackend) and use that method to inject it into the constructor of UsarioValidator.


Async Custom Validator with API
#3

an additional to that you should use the provided interfaces of angular to implement a custom validator (or validation function) or async validator (validation function). :wink:


#4

thanks friend! I have solved it!