4

I am trying to dynamically validate the custom-text-input based on service call result. If its true means jumpyId is available to use otherwise show error. My issue right now is when I update this.isAvailable from fromEvent its not reflecting the value in custom directive. I am expecting if api call return true, then directive should receive true otherwise false.

AvailableDirective.ts

import { Directive, forwardRef, Input } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
  selector: 'custom-text-input[vendorAvailable][formControlName],custom-text-input[vendorAvailable][formControl],custom-text-input[vendorAvailable][ngModel]',
  providers: [
    { provide: NG_VALIDATORS, useExisting: AvailabilityDirective, multi: true }
  ]
})
export class AvailabilityDirective implements Validator {

  @Input('available') available: boolean;
  validate(c: AbstractControl): { [key: string]: any } {
    console.log("valid", this.available);
    if (!this.available) {
      return {
        available: false
      };
    }
    return null;
  }
}

EventObservable:

fromEvent(this.custom.nativeElement, 'keyup').pipe(
      map((event: any) => {
        return event.target.value;
      })
      , debounceTime(1000)
      , distinctUntilChanged()
    ).subscribe((text: string) => {
      this.myService.isAvailable(text).subscribe((res) => {
        console.log(res);
        if (res) {
          this.isAvailable = true;
        } else {
          this.isAvailable = false;
        }
      }, (err) => {
        console.log(err);
      });
    });

template:

<custom-text-input *ngIf="drawer"
                                           label="JumpyId"
                                           [(ngModel)]="jumpyId"
                                           id="jumpyId"
                                           name="jumpyId"
                                           required
                                           [available]="isAvailable"
                                           #custom>
                        </custom-text-input>
1
  • The problem is not the new value s not received. If you used a setter or an ngOnCHanges, you could easily chck that. The problem is that yu expect the validate method to be called again even though the form control value hasn't changed. Commented Dec 9, 2019 at 22:23

1 Answer 1

7

Add an onChanges that watches for changes to available

onChange: () => void;

registerOnValidatorChange(fn: () => void): void {
  this.onChange = fn;
}

ngOnChanges(changes: SimpleChanges): void {
  if ('available' in changes) {
    if (this.onChange) {
      this.onChange();
    }
  }
}

If my validation directives rely on another input I use this validator base

https://stackblitz.com/edit/angular-cfexiy

Sign up to request clarification or add additional context in comments.

3 Comments

I learnt something today, thanks. Is there some similar mechanism available when yo want to simply add a validator to a FormControl in a reactive form and want the validator to revalidate if something other than the FormCOntrol value changes (other than revalidating explicitly)?
Not sure sorry, I only use template forms.
Thanks @AdrianBrand

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.