Rajib
Rajib

Reputation: 41

Angular Firebase Expected validator to return Promise or Observable

I have tried to check the if same email address exist or not while completing a reactive sign-up forms. I am wondering it is throwing error. Please tell me how to solve this error.

Expected validator to return Promise or Observable

Here is my code

email.validator.ts

import { AbstractControl, ValidationErrors } from '@angular/forms';
import { AngularFireDatabase } from '@angular/fire/database';
import { map } from 'rxjs/operators';

export class EmailValidator {

    constructor() {
    }

    static emailShouldUnique(db: AngularFireDatabase) {
        let users;
        let rawUsers: string[] = [];
        return (control: AbstractControl) => {
            return new Promise((resolve, reject) => {
                db.list('/users').snapshotChanges().pipe(
                    map(changes =>
                        changes.map(a => ({
                            key: a.payload.key, ...a.payload.val() as {}
                        }))))
                    .subscribe(data => {
                        users = data;
                        for (let index in users) {
                            rawUsers.push(users[index].email);
                        }
                        if (rawUsers.includes(control.value)) {
                            resolve({ mailSouldUnique: true })
                        }
                        else resolve(null);
                    })
            })
        }
    }
}

sign-up.component.ts


import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth.service';
import { Validators, FormBuilder } from '@angular/forms';
import { PasswordValidator } from './password.validators';
import { EmailValidator } from './email.validator';

@Component({
  selector: 'sign-up',
  templateUrl: './sign-up.component.html',
  styleUrls: ['./sign-up.component.css']
})
export class SignUpComponent {

  form;

  constructor(fb: FormBuilder, private auth: AuthService) {

    this.form = fb.group({
      fullName: ['', Validators.required],
      email: ['',
        [Validators.required, Validators.email],
        [EmailValidator.emailShouldUnique]
      ],
      phoneNumber: ['', Validators.required],
      password: ['', Validators.required],
      repeatPassword: ['', Validators.required]
    }, {
      validator: PasswordValidator.passwordShouldMatch
    })
  }

  get fullName() {
    return this.form.get('fullName');
  }
  get email() {
    return this.form.get('email');
  }
  get phoneNumber() {
    return this.form.get('phoneNumber');
  }
  get password() {
    return this.form.get('password');
  }
  get repeatPassword() {
    return this.form.get('repeatPassword');
  }
}

Here is the HTML markup to show the errors in the browser

<div class="form-group input-group">
                    <div class="input-group-prepend">
                        <span class="input-group-text"> <i class="fa fa-envelope"></i> </span>
                    </div>
                    <input name="email" formControlName="email" class="form-control" placeholder="Email address"
                        type="email">
                </div> <!-- form-group// -->
                <div class="alert alert-danger" *ngIf="email.touched && email.invalid">
                    <div *ngIf="email.errors.required">
                        Email Address is required.
                    </div>
                    <div *ngIf="email.errors.email">
                        Provided Email is not valid.
                    </div>
                    <div *ngIf="email.errors.shouldBeUnique">
                        Provided email is taken.
                    </div>

                </div>

Upvotes: 0

Views: 96

Answers (1)

Carlos Jafet Neto
Carlos Jafet Neto

Reputation: 891

I think you forget to return your promise:

 return (control: AbstractControl) => {
        return new Promise((resolve, reject) => {

Also try to let all validators inside the same array:

email: ['',
    [Validators.required, Validators.email, EmailValidator.emailShouldUnique]
  ]

Upvotes: 1

Related Questions