# How to add custom async validators in Angular

**URL:** <https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80>\
**Category:** General\
**Created:** [September 10, 2020, 3:16pm UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80 "2020-09-10T15:16:27Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [September 10, 2020, 3:16pm UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/1 "2020-09-10T15:16:27Z")

</div>

I cloned the [Angular seed project](https://github.com/eclipsesource/jsonforms-angular-seed) and have implemented a suitable schema/uischema and some mock data.  
However I’m struggling to figure out how to wire up a custom text input validator that must call a backend service to validate its input and display an error if invalid.  
I tried creating a custom component by copying TextControlRenderer and adding the relevant parts from custom.autocomplete.ts, but there are several problems:

1. `this.form.valueChanges` seems to generate events when editing all other inputs than the custom component (e.g. a TextControlRenderer)

2. I cannot seem to reliably add an error to the component when the service call has been resolved and the result is an error. Sometimes the component is marked invalid (red underline) and sometimes not. Also the spinner is not showing up, or sometimes showing up and not disappearing.

What am I doing wrong?  
Disclaimer: I’m pretty rusty with web dev  
Thanks

My component:

```auto
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {JsonFormsAngularService, JsonFormsControl} from '@jsonforms/angular';
import {ValidationService} from "./validation/validation.service";
import {debounceTime, finalize, switchMap, tap} from "rxjs/operators";

@Component({
  selector: 'MyTextControlRenderer',
  template: `
    <mat-form-field fxFlex [fxHide]="hidden">
      <mat-label>{{ label }}</mat-label>
      <input
        style="background-color: aquamarine"
        matInput
        [type]="getType()"
        (input)="onChange($event)"
        [id]="id"
        [formControl]="form"
      />
      <mat-option *ngIf="isLoading" class="is-loading">
        <mat-spinner diameter="30"></mat-spinner>
      </mat-option>
      <mat-hint *ngIf="shouldShowUnfocusedDescription()">{{ description }}</mat-hint>
      <mat-error>{{ error }}</mat-error>
    </mat-form-field>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyTextControlRenderer extends JsonFormsControl {
  isLoading: boolean;

  constructor(jsonformsService: JsonFormsAngularService, private validationService: ValidationService) {
    super(jsonformsService);
  }

  ngOnInit() {
    super.ngOnInit();
    console.log(JSON.stringify(this.form));
    this.form.valueChanges
      .pipe(
        tap(() => console.log("onChange")),
        debounceTime(300),
        tap(() => this.isLoading = true),
        switchMap(value => this.validationService.validateCareTeam(value)
          .pipe(
            finalize(() => {
              console.log("finalize")
              return this.isLoading = false;
            })
          )
        )
      )
      .subscribe(isValid => {
        console.log("next value: " + isValid)
        this.form.setErrors({invalid: true});
        //if (!isValid) this.error = "invalid"; <-- not working either
      });
  }

  getEventValue = (event: any) => event.target.value;
  getType = (): string => {
    if (this.uischema.options && this.uischema.options.format) {
      return this.uischema.options.format;
    }
    if (this.scopedSchema && this.scopedSchema.format) {
      switch (this.scopedSchema.format) {
        case 'email':
          return 'email';
        case 'tel':
          return 'tel';
        default:
          return 'text';
      }
    }
    return 'text';
  };
}

```

My service class:

```auto
export class ValidationService {

  constructor(private http: HttpClient) { }

  validateCareTeam(ref: String): Observable<boolean> {
    // return this.http.get<boolean>('./asdf');
    console.log("service called")
    return of(false).pipe(delay(1000));
  }
}

```

_[[original thread](https://spectrum.chat/jsonforms/general/how-to-add-custom-async-validators-in-angular~1356994e-7c5f-4d1d-bb52-b6ec5989c235) by Tue Toft Nørgård]_

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [September 21, 2020, 3:10pm UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/2 "2020-09-21T15:10:19Z")

</div>

Hi @tue-cn(tue-cn), to show custom errors you don’t need your own renderer. You can send the data to validate to your service, and, once complete, you can set an appropriate error in JSON Forms. Via the error path you can control where the error shall be shown. For this you can use the `updateErrors` action which you can execute against the core in the `JsonFormsAngularService`.

---

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [March 5, 2021, 1:50pm UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/3 "2021-03-05T13:50:06Z")

</div>

_[Fioyesuraj]_

hi @sdirix(sdirix) , Can you show me example how to use the updateErrors in angular …

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [March 5, 2021, 3:10pm UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/4 "2021-03-05T15:10:07Z")

</div>

Hi @fioyesuraj(fioyesuraj), just to be clear: In general we don’t recommend setting custom errors but adding them via Ajv customization. Only if that really isn’t applicable you might want to use `updateErrors`.

If you really need to do it you can for example execute `this.jsonFormsService.updateCore(Actions.updateErrors(newErrors));` within a renderer.

---

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [March 8, 2021, 6:23am UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/5 "2021-03-08T06:23:43Z")

</div>

_[Fioyesuraj]_

hi @sdirix(sdirix) i have update the errors based on your suggestion …i can able to get value only at the time of code hit in debugger (this.error) after code run in html {{ error}} i could not get the value …Meanwhile when error is thrown save button should not allow to submit …

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [March 8, 2021, 8:27am UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/6 "2021-03-08T08:27:10Z")

</div>

You can listen to the emitted errors via the root json forms component. When there are some you can disable your save button.

---

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [March 9, 2021, 5:22am UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/7 "2021-03-09T05:22:57Z")

</div>

_[Fioyesuraj]_

root json forms component means? i could not get you properly … can you explain clearly?

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [March 9, 2021, 10:40am UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/8 "2021-03-09T10:40:52Z")

</div>

In your Angular application you need to invoke JSON Forms at some place. In the Angular seed it is the `app` component. There you can not only bind to the `data` but also `errors` are emitted.

---

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [March 9, 2021, 1:05pm UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/9 "2021-03-09T13:05:37Z")

</div>

_[Fioyesuraj]_

Hi Team ,

---

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [March 9, 2021, 1:07pm UTC](https://jsonforms.discourse.group/t/how-to-add-custom-async-validators-in-angular/80/10 "2021-03-09T13:07:22Z")

</div>

_[Fioyesuraj]_

Thanks for the update … I got it … I have another question …how to remove the updated errors …for eg.i want to empty this.jsonformsService.getState().jsonforms.core.errors=[]; ho can i achieve this
