Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide async parameter to custom Angular validators

I'm setting up form validators where the min & max of multiple fields are fetched via a single API. The app crashes when trying to pass one of those async values to a custom validator parameter, but it'll work when the value's hard-coded.

The error received when passing an async value is the following:

ERROR Error: formGroup expects a FormGroup instance. Please pass one in.

file.ts:

export class PackageDimensionValidator {
   static validSize(min: number, max: number): ValidatorFn {
      return (control: AbstractControl): { [key: string]: boolean } | null => {
      if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
        return { 'exceedRange': true };
      }
      return null;
    };
   }
}

// ... 

ngOnInit() {
   // Retrieve maximum package dimensions for input data validation.
   this.shipmentService.getMaxPackageSize()
      .subscribe(result => {
         this.packageRestrictions = new PackageRestrictions(result);
         console.dir(this.packageRestrictions);
         this.setupPackageValidators();
   });
}

setupPackageValidators() {
   const maxWidth = this.packageRestrictions.maxWidth; // Crashes on Async value.
   // const maxWidth = 5; // Works on hard-coded value.

   // Setup package dimension validators.
   this.packageSizeForm = this.formBuilder.group({
      maxWidth: new FormControl('', Validators.compose([
         PackageDimensionValidator.validSize(null, maxWidth),
         // Other validators ...
      ]))
   });
}

file.html:

<form [formGroup]="packageSizeForm">
   <input formControlName="maxWidth" type="text" required />
</form>

Ideally, there will be multiple formControls each with unique min & max's, all fetched at the same time by a single API. The thought process was to call that API, store its result locally, then build the form validators. I'm now questioning the order of this sequence.

like image 404
Devon Fazekas Avatar asked Dec 17 '25 20:12

Devon Fazekas


1 Answers

I'm not completely sure that the error message you're getting reflects the issue you described. I'd start with Initiating packageSizeForm in your ngOnInit without validators:

ngOnInit() {
   this.packageSizeForm = new FormGroup({
          maxWidth: new FormControl('');
   });
   this.shipmentService.getMaxPackageSize()
      .subscribe(result => {
         this.packageRestrictions = new PackageRestrictions(result);
         console.dir(this.packageRestrictions);
         this.setupPackageValidators();
   });
}

Then set the validators in this.setupPackageValidators();:

setupPackageValidators() {
   this.packageSizeForm.get('maxWidth').clearValidators();
   this.packageSizeForm.get('maxWidth').setValidators(Validators.compose([
     PackageDimensionValidator.validSize(null, maxWidth)]);
   this.packageSizeForm.get('maxWidth').updateValueAndValidity();
}
like image 56
noamyg Avatar answered Dec 19 '25 13:12

noamyg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!