1
votes

i create function muchmatch in ReactiveFormsModule , But when testing, found that there was an error meassege in Angular and I don't really know why.

"Error: Expected validator to return Promise or Observable."

import { Component, OnInit } from '@angular/core';
import { UserService } from '../service/user.service';
import { Router} from '@angular/router';

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-login-register',
  templateUrl: './login-register.component.html',
  styleUrls: ['./login-register.component.css']
})
export class LoginRegisterComponent implements OnInit {

  registerForm: FormGroup;
  submitted = false;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.registerForm = this.formBuilder.group({
      name: ['', Validators.required],
      lastName: ['', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      password: ['', [Validators.required, Validators.minLength(6)]],
      confirmPassword: ['', Validators.required, this.mustMatch('password', 'confirmPassword')],
      passwordHint: ['', [Validators.required, Validators.minLength(6)]],
      confirmPasswordHint: ['', Validators.required , this.mustMatch('passwordHint', 'confirmPasswordHint')],
    });
  }

  // convenience getter for easy access to form fields
  get f() { return this.registerForm.controls; }

// When Submit

  onSubmit() {

      this.submitted = true;

      // stop here if form is invalid
      if (this.registerForm.invalid) {
          return;
      }

      alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.registerForm.value));
  }

//Function Check password

  mustMatch(p1 , p2) {

      return (registerForm: FormGroup) => {

      let pass1 = this.registerForm.controls[p1];
      let pass2 = this.registerForm.controls[p2];

      // if (pass1.errors && !pass2.errors.mustMatch) {
      //   return;
      // }

      if (pass1.value !== pass2.value) {
        pass2.setErrors({mustMatch: true});
      } else {
        pass2.setErrors(null);
      }
    }
  }   
}

// Code Show form register Data Resive to backend error when Fill out the information in the column passwordconfirm , passwordHintconfrim

<form [formGroup]="registerForm" (ngSubmit)="onSubmit()" style="width: 500px">

    <div class="form-group">
        <label>First Name</label>
        <input type="text" formControlName="name" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.name.errors }"
        placeholder="input your name">
        <div *ngIf="submitted && f.name.errors" class="invalid-feedback">
            <div *ngIf="f.name.errors.required">First Name is required</div>
        </div>
    </div>

    <div class="form-group">
        <label>Last Name</label>
        <input type="text" formControlName="lastName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.lastName.errors }"
        placeholder="input your name">
        <div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
            <div *ngIf="f.lastName.errors.required">Last Name is required</div>
        </div>
    </div>

    <div class="form-group">
        <label>Email</label>
        <input type="text" formControlName="email" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.email.errors }"
        placeholder="input your name">
        <div *ngIf="submitted && f.email.errors" class="invalid-feedback">
            <div *ngIf="f.email.errors.required">Email is required</div>
            <div *ngIf="f.email.errors.email">Email must be a valid email address</div>
        </div>
    </div>
<!--Password-->
    <div class="form-group">
        <label>Password</label>
        <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.password.errors }"
        placeholder="input your name">
        <div *ngIf="submitted && f.password.errors" class="invalid-feedback">
            <div *ngIf="f.password.errors.required">Password is required</div>
            <div *ngIf="f.password.errors.minlength">Password must be at least 6 characters</div>
        </div>
    </div>
    <div class="form-group">
        <label>Confirm Password</label>
        <input type="password" formControlName="confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.confirmPassword.errors }"
        placeholder="input your name">
        <div *ngIf="submitted && f.confirmPassword.errors" class="invalid-feedback">
            <div *ngIf="f.confirmPassword.errors.required">Confirm Password is required</div>
            <div *ngIf="f.confirmPassword.errors.mustMatch">Passwords must match</div>
        </div>
    </div>
<!--Password Hint-->
    <div class="form-group">
        <label>PasswordHint</label>
        <input type="password" formControlName="passwordHint" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.passwordHint.errors }"
        placeholder="input your name">
        <div *ngIf="submitted && f.passwordHint.errors" class="invalid-feedback">
            <div *ngIf="f.passwordHint.errors.required">Password is required</div>
            <div *ngIf="f.passwordHint.errors.minlength">Password must be at least 6 characters</div>
        </div>
    </div>
    <div class="form-group">
        <label>Confirm PasswordHint</label>
        <input type="password" formControlName="confirmPasswordHint" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.confirmPasswordHint.errors }"
        placeholder="input your name">
        <div *ngIf="submitted && f.confirmPasswordHint.errors" class="invalid-feedback">
            <div *ngIf="f.confirmPasswordHint.errors.required">Confirm Password is required</div>
            <div *ngIf="f.confirmPasswordHint.errors.mustMatch">Passwords must match</div>
        </div>
    </div>

    <div class="form-group">
        <button class="btn btn-primary">Register</button>
    </div>
</form>
1

1 Answers

4
votes

When working with FormBuilder you should know that most common used syntax is the following:

this.fb.group({
  property: [value, syncValidator|s, asyncValidator|s]
})

Now let's look at what you've written:

confirmPasswordHint: ['', Validators.required , this.mustMatch(...)]
                             \/                         \/
                         syncValidator             asyncValidator

But you probably wanted:

confirmPasswordHint: ['', [Validators.required , this.mustMatch(...)]]
                                               \/
                                  Array of syncValidators

Cheat Sheet for FormBuilder

Which parameters it can take:

enter image description here

Use cases:

enter image description here