简体   繁体   中英

Angular 4 - Using Asynchronous custom validators

I have the following code:

HTML:

<div [class]="new_workflow_row_class" id="new_workflow_row">
    <div class="col-sm-6">
        <label class="checkmark-container" i18n>New Workflow
            <input type="checkbox" id="new-workflow" name="new-workflow" [(ngModel)]="new_checkbox" (click)="uncheckBox($event, 'edit')"> 
            <span class="checkmark" id="new-workflow-checkmark" [class]="checkmark_class"><span id="new-workflow-checkmark-content"></span>{{checkmark_content}}</span>
        </label>
        <input type="text" *ngIf="new_checkbox" id="new_workflow_name" name="new_workflow_name" (keyup)="clearWorkflowError(true)" [(ngModel)]="new_workflow" placeholder="Enter Workflow Name">
        <p [hidden]="!show_workflow_error && !workflowForm.errors" class="workflow-error" i18n>The workflow name already exists. Please use a different name.</p>
    </div>
</div>

Component.ts:

duplicateWorkflowValidator(control: FormControl) {
    console.log("this validator was called!");
    clearTimeout(this.workflowTimeout);

    return new Promise((resolve, reject) => {
        if (this.new_workflow != '') {
            this.workflowTimeout = setTimeout(() => {
                this
                    .requestService
                    .findWorkflow(control.value)
                    .subscribe((results: any) => {
                        let data: any = results.data;

                        if (data.duplicate) {
                            resolve({ duplicateWorkflow: { value: control.value}})
                        }
                        else if (results.status == "OK") {
                            resolve(null);
                        }
                    })
                ;
            }, 500);
        }
        else {
            resolve(null);
        }


    })

}

Inside constructor for component.ts:

this.workflowForm = new FormGroup({
    name: new FormControl(this.new_workflow, [
        Validators.required,
    ], this.duplicateWorkflowValidator.bind(this))
});

I am trying to bind this asynchronous validator to the reactive form but it's not working. I want to use the duplicateWorkflowValidator inside workflowForm and have it trigger an error message when it finds a duplicate workflow.

How do I a) bind the validator to the reactive form properly, b) access the validator errors? Thanks in advance, hopefully this makes sense.

You are mixing template forms with reactive forms. Chose one approach. In the below example I am using reactive forms.

Try this simplified version. For demonstration purposes below the validator will fail when I type test , but succeed when I type anything else. You will need to change that to your service call.

https://angular-sjqjwh.stackblitz.io

Template:

<form [formGroup]="myForm">
    <div>
        <div>
            <input type="text" formControlName="name">
            <div *ngIf="myForm.controls.name.hasError('duplicateWorkflow')">
                Workflow already exists!
            </div>
            {{ myForm.controls.name.hasError('duplicateWorkflow') | json }}
        </div>
    </div>
</form>

Component

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators, Form, FormBuilder } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  workflowTimeout: number = 0;
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.myForm = this.fb.group({
      name: new FormControl('', 
        [Validators.required], 
        this.duplicateWorkflowValidator.bind(this))
    });
  }

  duplicateWorkflowValidator(control: FormControl) {
    console.log("this validator was called!");

    return new Promise((resolve, reject) => {
      if (control.value === 'test') {
        this.workflowTimeout = setTimeout(() => {
          resolve({ duplicateWorkflow: { value: control.value } })
        }, 500);
      }
      else {
        resolve(null);
      }
    });
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM