14

I'm trying to make a custom Angular 2 form Validator to check if a user exist on a data base.

This is the code of my custom form Validator

import { FormControl } from '@angular/forms';
import {API} from "../services/api";
import {ReflectiveInjector} from "@angular/core";

export class EmailValidator {

  constructor() {}

  static checkEmail(control: FormControl,): any {
    let injector = ReflectiveInjector.resolveAndCreate([API]);
    let api = injector.get(API);

    return api.checkUser(control.value).then(response => {
      response;
    });

  }

}

And this is this is my custom service which is responsible for make the request to a node api on backend

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';

@Injectable()
export class API {
  private backendUrl = 'http://127.0.0.1:5000/api/register/';

  constructor(private http: Http) { }

  checkUser(email:string): Promise<any> {
    return this.http.get(this.backendUrl + email)
      .toPromise()
      .then(response => response.json())
      .catch(this.handleError);
  }

When I try to validate a user this is the error that is showed

EXCEPTION: Error in ./TextInput class TextInput - inline template:0:0 caused by: No provider for Http! (API -> Http)

What I'm doing wrong?

Thanks

Hanzo
  • 1,677
  • 3
  • 20
  • 44

1 Answers1

22
@Injectable()
export class EmailValidator {

  constructor(private api:API) {}

  /* static */ checkEmail(control: FormControl,): any {
    return this.api.checkUser(control.value).then(response => {
      response;
    });
  }
}

Add it to of @NgModule() or @Component() depending on what scope you want it to have

providers: [EmailValidator]

Inject it to the component where you want to use it

export class MyComponent {
  constructor(private emailValidator:EmailValidator, fb:FormBuilder){}

  this myForm = fb.group({
    email: [], [this.emailValidator.checkEmail.bind(this.emailValidator)]
  });
}
Günter Zöchbauer
  • 490,478
  • 163
  • 1,733
  • 1,404
  • 1
    Thanks!, you save my day. I didn't know how to use a custom service on this way into the `formBuilder.group` – Hanzo Mar 07 '17 at 11:13
  • Sorry one more question. On the `EmailValidator` if the mail exist, what would be to return? I mean that `return this.api.CheckUser(control.value).then(response => { if(response.msg === "Exist") { response; } else { null; } }); }` In both cases the validations is succesful, What would be to return if the user exist? – Hanzo Mar 07 '17 at 11:38
  • 1
    For example `return { error: 'User exists'};` or whatever else information you want to get in case of an error. – Günter Zöchbauer Mar 07 '17 at 12:00
  • Thanks you're right. Definitely today is not my day. – Hanzo Mar 07 '17 at 12:39
  • 2
    Great solution, especially binding the validator. – Faiz Mohamed Haneef Apr 13 '18 at 13:08