Why asyncValidators dones’t invoke unless all the fields are without errors?

I create fooValidation (async validation function) that return observable (in form-level).

The problem is the inner function doesn’t invoke unless all the fields are without errors.

This is mean when type in age field I can see that inner fooValidation is invoke and it’s good.

But when I click the button setError and set error to firstname and then I type on age field, the inner function of fooValidation doesn’t invoke, which is not good because in this function I want to check a lot of fields and set/remove the errors.

I want to invoke the async function anyway. regardless if I have an error or not. because this function should set or remove error on some fields according my logic.

Any idea how to solve that?

codesandbox

import { Component } from "@angular/core";
import { FormControl, FormGroup, Validators } from "@angular/forms";
import { of } from "rxjs";

const fooValidation = () => {
  console.log("in fooValidation");
  return (control) => {
    console.log("in inner fooValidation");

    const myLogicReturns = null; // no errors for now..
    return of(myLogicReturns);
  };
};

@Component({
  selector: "app-root",
  template: `
    <h1>validation</h1>

    <form [formGroup]="form" (ngSubmit)="submit()">
      firstname: {{ firstname.errors | json }}<br />
      lastname: {{ lastname.errors | json }}<br />
      age: {{ age.errors | json }}<br />
      <br />

      <input formControlName="firstname" placeholder="firstname" />
      <br />

      <input formControlName="lastname" placeholder="lastname" />
      <br />

      <input formControlName="age" placeholder="age" />
      <br />

      <button type="submit">submit</button>
      <br />
      <button type="button" (click)="setError()">setError</button>
    </form>
  `
})
export class AppComponent {
  title = "CodeSandbox";

  form = new FormGroup(
    {
      firstname: new FormControl(""),
      lastname: new FormControl(""),
      age: new FormControl("")
    },
    { asyncValidators: fooValidation() }
  );

  get firstname() {
    return this.form.get("firstname");
  }
  get lastname() {
    return this.form.get("lastname");
  }
  get age() {
    return this.form.get("age");
  }

  submit() {
    console.log("in submit!");
  }

  setError() {
    console.log("in setError");

    this.firstname.setErrors({ someError: true });
  }
}

Source: Angular Questions