Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async validation is triggered multiple times on form.setValues()

I'm using Angular 5, reactive forms approach.

I have a form inside an Angular Material dialog that I am using for both entering and editing data. My constructor looks like this:

constructor(public formBuilder: FormBuilder,
    public documentService: DocumentService, 
    @Inject(MAT_DIALOG_DATA) public data: any) {
    this.createForm();
    if (this.data.edit) {
        this.setValues();
    }
    this.setTitles();
}

The createForm call creates the reactive form where I have the async validation:

createForm() {
    this.documentForm = this.formBuilder.group({
        ...
        documentNumber: new FormControl('',
                {
                    updateOn: 'blur',
                    validators: [Validators.required],
                    asyncValidators: [this.checkDocumentNumber.bind(this)]
                }),

        ...
    });
}

If the dialog is in 'edit' mode, the setValues call patches the data that needs to be edited:

setValue() {
    this.form.patchData({
        ...
        documentNumber: this.data.document.documentNumber
        ...
    });
}

The setTitles call sets the dialog title.

The checkDocumentNumber call gets a boolean value from the server:

checkDocumentNumber(control: AbstractControl): Observable<ValidationErrors | null> {
    const formValue = this.form.value;
    return this.documentService
        .checkDocumentNumber(new Document(this.data.edit ? this.data.document.id : 0,
            form.documentNumber)).pipe(map((response: boolean) => {
            return response ? { inUse: true } : null;
        }));
}

The API call made is:

checkDocumentNumber(doc: Document) {
    return this.http.post(`/Documents/Inbox/CheckDocumentNumber`, doc);
}

The form dialog in 'edit' mode is called like this:

this.dialogService.open(DocumentDialogComponent,
    {
        data: {
            edit: true,
            document: this.document
        }
    });

The issue I'm having is that when I open the dialog to edit the document data, 9 API calls are made to check the document number. The first 5 are cancelled, then one that returns 200, another one that is cancelled and finally two more that return 200.

The same scenario in a different part of the app gets me 3 cancelled and two 200 calls.

How do I stop angular from making these unnecessary API calls? Before Angular 5, the updateOn flag wasn't there so I thought that with that out, this won't be happening.

Here's a screenshot of the API calls being made:

API calls being made

like image 600
GregoryHouseMD Avatar asked Nov 18 '22 05:11

GregoryHouseMD


1 Answers

You can use debouncePromise function to reduce the trigger times. It may be caused by the re-render of view.

asyncValidators: [debouncePromise(this.checkDocumentNumber.bind(this))]
like image 165
zayn Avatar answered Dec 06 '22 11:12

zayn