-1

I have created 2 almost identical async validators.

uniqueTitleValidator - This validates for existing string with a simple array 'titles'

titleExist(title: string): Observable<boolean> {
    return of(title).pipe(
      map((title) => {
        const titles = ['abc', '123'];
        return titles.includes(title);
      })
    );
  }

  uniqueTitleValidator(): AsyncValidatorFn {
    return (control: AbstractControl): Observable<ValidationErrors | null> => {
      return this.titleExist(control.value).pipe(
        map((exists) => {
          console.log('exists title', exists);
          return exists ? { titleExist: true } : null;
        })
      );
    };
  }

uniqueVoucherValidator - This validates for an existing string by retrieving data from FireStore

voucherExist(title: string, paymentService: PaymentService): Observable<any> {
    return paymentService.getAllPayment().pipe(
      map((payments) => {
        console.log('payments', payments);
        const payment = payments.find(
          (item: any) =>
            item.data.voucherTitle.toLowerCase() == title.toLowerCase()
        );
        console.log('payment validator', payment);
        return !!payment;
      })
    );
  }

  uniqueVoucherValidator(paymentService: PaymentService): AsyncValidatorFn {
    return (control: AbstractControl): Observable<ValidationErrors | null> => {
      return this.voucherExist(control.value, paymentService).pipe(
        map((exists) => {
          console.log('exists voucher', exists);
          return exists ? { voucherExist: true } : null;
        })
      );
    };
  }

Both works and from the screen shot console - you can see the boolean for 'exists title' and 'exist voucher' are returned correctly. However, only the second validator - uniqueVoucherValidator - the validation error is always reflected as null.

form.control.voucherTitle.errors is reflecting the correct validation result

form.control.voucherTitle.errors is always null

Need some advice on what could have caused the uniqueVoucherValidator to always show null.

2
  • Can you please show us how you assign them in your component code, ideally a stackblitz showing the issue you're facing is better Commented Sep 13, 2022 at 17:03
  • You didnt show how you use your valdiators. Commented Sep 13, 2022 at 17:47

1 Answer 1

2

Since Firebase api has not completed.The form control is still in pending status you can use take(1) operator to complete observable manually

voucherExist(title: string, paymentService: PaymentService): Observable<any> {
    return paymentService.getAllPayment().pipe(
      map((payments) => {
        console.log('payments', payments);
        const payment = payments.find(
          (item: any) =>
            item.data.voucherTitle.toLowerCase() == title.toLowerCase()
        );
        console.log('payment validator', payment);
        return !!payment;
      }),
      take(1)
    );
  }
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.