Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ngSubmit should trigger after Asynchronous Validation completesΒ #31021

@DibyodyutiMondal

Description

@DibyodyutiMondal

πŸš€ feature request

Relevant Package

This feature request is for @angular/forms

Specifically, Reactive Forms

Description

**in Template**
<form [formGroup]="myFormGroup" (ngSubmit)="mFG_submit()"></form>

**In Component**
mFG_submit() {
   if (!myFormGroup.valid)
      return;

   //logic that will run if and only if the entire form is valid after both 
      sync and async validators have finished executing
}

The problem with the above code is that if myFormGroup has any controls with asynchronous validators, then ngSubmit is triggered after the async validators have started executing, but before they have finished executing. As as result, when the 'if' gate inside mFG_submit() is hit, it returns immediately, because the form status is 'PENDING'. As a result, even if the asynchronous validator returns true, i,e, the control is valid, the submission logic is never executed.

Describe the solution you'd like

One solution is to check on every submit if the form status is "PENDING", and then listen to status changes, and emit ngSubmit again, the moment status changes. I would like to have such behaviour provided by the framework
Currently, I use this directive

@Directive({
    selector: 'form[formGroup]'
})
export class ResubmitIfPendingDirective {
    constructor(
        private fgd: FormGroupDirective
    ) {
        this.subscriptions.add(this.resubmission_sub);
    }
    private subscriptions: Subscription = new Subscription();
    private resubmission_sub: Subscription = new Subscription();

    ngOnInit() {
        //listen to ngSubmit of the form
        this.subscriptions.add(this.fgd.ngSubmit.subscribe(() => {
            //if you are already subscribed to status changes, unsubscribe
            this.subscriptions.remove(this.resubmission_sub);
            this.resubmission_sub.unsubscribe();

            //if your form is PENDING when submitted, subscribe to status changes
            if (this.fgd.control.pending) {
                this.resubmission_sub = this.fgd.control.statusChanges
                    .pipe(

                        //don't do anything if new emitted status is PENDING 
                        filter(() => !this.fgd.control.pending),

                        //status no longer PENDING, time to resubmit
                        //and stop observing statusChanges
                        first()
    
                        // above 2 pipes can be combined, I separated for clarity
                        // first(() => !this.fgd.control.pending)

                       
                    ).subscribe(() => this.fgd.ngSubmit.emit());
                this.subscriptions.add(this.resubmission_sub)

                //since the validation has already been run, 
                //and there have no change in the values of the controls,
                //the status of this follow-up ngSubmit will either emit 
                //VALID or INVALID
                //therefore, the ngSubmit we emit will simply 
                //unsubscribe resubmission_sub
                //and never re-enter this if() block
                //Thus, No infinite loop of submits
            }
        }));
    }
    ngOnDestroy() {
        //stop listening to ngSubmit and status changes
        this.subscriptions.unsubscribe();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: formsforms: validatorshelp wantedAn issue that is suitable for a community contributor (based on its complexity/scope).type: bug/fix

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions