Subjugation
Subjugation

Reputation: 105

How to turn a function into an async validator for a formcontrol in Angular8?

I have a form control of type date that allows the user to pick a date. I want to create an async validator that checks if the the date submitted already exists x amount of times in my database. If so, provide an error along the lines of:

order.get('DateOfDelivery').errors?.exists

I've created this function inside my class shop component (and it works against my db. it comes back with the appropriate amount of orders on queried date):

  checkDeliveriesDate(event) {
    console.log(event.target.value);
    let date = { date: event.target.value };
    this.SS.getOrdersPerDate(date).subscribe(
      res => {
        console.log(res);
        /*
        if (res.length>3){
          formcontrol for e should turn invalid 
        }
        else{
          valid
        }
        */
      },
      err => {
        console.log(err);
      }
    )
  }

here's the form control. I know that the async validator needs to be the third argument-

DateOfDelivery: new FormControl('', Validators.required),/*AsyncValidatorHere*/),

Here's the HTML-

<input type="date" class="form-control" formControlName="DateOfDelivery" (change)='checkDeliveriesDate($event)'>

I appreciate the help. Thank you in advance

Edit:

checkDeliveriesDateValidator(ctrl: AbstractControl) {

  if (!ctrl || String(ctrl.value).length === 0) {
    console.log("!c|| String (c.value).length ===0")
    return null;

  }

  return (ctrl && ctrl.value) ? this.SS.getOrdersPerDate({ date: ctrl.value }).pipe(
    map(res => {
      let deliveriesDate:any=res;
      console.log(deliveriesDate);
      if (deliveriesDate.length>3){ 
        return {exists: true};
      }
      else{
        return null;
      }
    })
  ) : null;
}

The async validator is producing this error-

ERROR TypeError: Cannot read property 'SS' of undefined

Upvotes: 0

Views: 59

Answers (1)

bryan60
bryan60

Reputation: 29355

you return the observable and use the map operator to transform the response into the validator return type, and also make it expect an abstract control as argument, like so:

 checkDeliveriesDateValidator(ctrl: AbstractControl) {
    // add in basic null checks
    return (ctrl && ctrl.value) ? this.SS.getOrdersPerDate({ date: ctrl.value }).pipe(
      map(res => {
        console.log(res);
        if (res.length>3){
          //formcontrol for e should turn invalid 
          return {exists: true};
        }
        else{
          return null;
        }
      })
    ) : null;
  }

then use like:

DateOfDelivery: new FormControl('', Validators.required, checkDeliveriesDateValidator)

Upvotes: 1

Related Questions