Custom Async Validator using an observable from ngrx store selector does not return 'null' unless I put take(1) operator

Form Group

colleges$ = this.store.select(getColleges);

this.personalFg = this.fb.group({
      college: ['',[Validators.required],[this.customValidatorWithinSelection(this.colleges$)]],
      course: ['',[Validators.required]],
    });

Custom Async Validator

customValidatorWithinSelection(options:Observable<any>): AsyncValidatorFn{
    return (control: AbstractControl): Observable<ValidationErrors | null> =>{
      return options.pipe(
          map(options=>{
            let selected = options.filter(college=>college.description === control.value);
            //console.log('validator',selected, control.value, selected.length > 0 ? null : {validate: 'error'})
            return selected.length > 0 ? null: {validate: 'error'};
          }),
          take(1),
      )
    }
  }

So far, my code works fine and I have what I needed but I want to understand why does the customValidatorWithinSelection always return false if I remove the take(1) operator.

>Solution :

It is important that the async validator observable completes, If you remove take(1) it can lead to unexpected behavior in the form field such as control that is stuck in a pending states.

You can check whether validator completes or not by accessing pending props from formControl

this.personalFg.get('college').pending // will return true if we remove take(1)

Leave a Reply