1

I am trying to implement a verify password validation with Angular 6 using Reactive Form but I can't get the best way to do it, below an example that works with "1234" but I would like to pass the value of the password control instead. I tried with ValidatePWD(this) but doesn't work either.

 //component.ts
 import { ValidatePWD } from './compare.validator';

 this.form = this._fb.group({
                  'user': ['', Validators.compose([Validators.required])],                       
                  'password': ['', Validators.compose([Validators.required])],
                  'verifypassword': ['', [Validators.required, ValidatePWD]],

 });


//compare.validator.ts
import { AbstractControl, FormGroup } from '@angular/forms';
export function ValidatePWD(control: AbstractControl ) {    
  if (control.value != "1234") {
    return { validPWD: true };
  }
  return null;
}


<div class="form-group">
      <label>Password: {{model.password}}</label>
      <input [(ngModel)]="model.password" [formControl]="password" class="form-control" type="password">
</div>

<div class="form-group">
     <label >Verify Password</label>
     <input[(ngModel)]="model.verifypassword" [formControl]="verifypassword"  class="form-control" type="password">
</div>

enter image description here

0

3 Answers 3

2

Option 1 - Validate the password and verifyPassword through FormGroup,

Here is simple sample code for confirm password validation where you need to pass the validator to FormGroup which contains both the contols password and confirmPassword.

  this.form = this._fb.group({
              'user': ['', Validators.compose([Validators.required])],                       
              'password': ['', Validators.compose([Validators.required])],
              'verifypassword': ['', [Validators.required]],

  }, { validator: this.passwordMatchValidator });

  passwordMatchValidator(g: FormGroup) {
    return g.get('password').value === g.get('verifypassword').value
       ? null : {'mismatch': true};
  }

html

<div *ngIf="form.invalid && form.errors['mismatch']">Password did not match</div>

Sample example is here -https://stackblitz.com/edit/confirm-password-q3ngps

Option 2 - Use a function to match the password.

password-validator.ts

export class PasswordValidation {

    static MatchPassword(AC: AbstractControl) {
        let password = AC.get('password').value;
        if(AC.get('confirmPassword').touched || AC.get('confirmPassword').dirty) {
            let verifyPassword = AC.get('confirmPassword').value;

            if(password != verifyPassword) {
                AC.get('confirmPassword').setErrors( {MatchPassword: true} )
            } else {
                return null
            }
        }
    }
}

Component ts

this.form = this._fb.group({
      password: ['', Validators.required],
      confirmPassword: ['', Validators.required]
    }, {
      validator: PasswordValidation.MatchPassword
    });

Working copy is here - https://stackblitz.com/edit/material-password-confirm-pnnd4t

Sign up to request clarification or add additional context in comments.

6 Comments

it works but only when i press the submit button, i wuold like to check the validation as soon as the user touch the verifypassword field
I think you had put the condition in html when to show the error. Share your html.
just because i am using the css ng-valid, ng-invalid, you know the validation password if is differents must be invalid ...after that if is invalid i can add a message
you can capture the error in FormGroup instead of FormControl of verify password itself. Updated the answer.
Please have a look to the question there is an image that show you that the field is valid even if there is a text that says 'password doesn't match' and this is not the effect that i am looking for. btw thank you so much for your help
|
0
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
import { globalRuleForm } from '../types/global-rule';

export function uniqueMainChildConditionValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        if (!Array.isArray(control.value)) {
            return null;
        }

        const mainObjects: globalRuleForm[] = control.value;
        const seenMainConditions = new Set<string>(); // Used to track already seen conditions of the main objects

        // Iterate over the main objects
        for (let i = 0; i < mainObjects.length; i++) {
            const mainObj = mainObjects[i];

            // Ensure the current main object has child conditions to check
            if (mainObj.ChildCondition && mainObj.ChildCondition.length > 0) {
                const seenChildConditions = new Set<string>(); // Set for duplicate child condition check

                // Check each child condition for duplication
                for (const [index, child] of mainObj.ChildCondition.entries()) {
                    const childConditionKey = `${child.Field}-${child.Condition}-${child.ConditionText}`;
                    const parentConditionKey = `${mainObj.Field}-${mainObj.Condition}-${mainObj.ConditionText}`;

                    // Check if the child condition matches the parent condition
                    if (childConditionKey === parentConditionKey) {
                        return { 
                            conditionMismatch: `Child condition in main object ${i + 1} matches the parent condition.` 
                        };
                    }

                    // Check if the child condition has been seen before (duplicate check)
                    if (seenChildConditions.has(childConditionKey)) {
                        return { 
                            conditionMismatch: `Child condition ${childConditionKey} is duplicated in main object ${i + 1}.` 
                        };
                    }

                    // Add the child condition to the set of seen conditions
                    seenChildConditions.add(childConditionKey);
                }
            }

            // Check for duplicates across all main objects (based on the field, condition, and conditionText)
            const mainConditionKey = `${mainObj.Field}-${mainObj.Condition}-${mainObj.ConditionText}`;
            if (seenMainConditions.has(mainConditionKey)) {
                return { 
                    conditionMismatch: `Main object ${i + 1} has matching properties with another main object.` 
                };
            }

            // Add the current main object condition to the set of seen main conditions
            seenMainConditions.add(mainConditionKey);
        }

        return null; // Return null if no issues found
    };
}

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
import { globalRuleForm } from '../types/global-rule';

export function uniqueMainChildConditionValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        if (!Array.isArray(control.value)) {
            return null;
        }
        const mainObjects: globalRuleForm[] = control.value;
        for (let i = 0; i < mainObjects.length; i++) {
            const mainObj = mainObjects[i];
            // Ensure the current main object has child conditions to check
            if (mainObj.ChildCondition && mainObj.ChildCondition.length > 0) {
                const seenChildConditions = new Set<string>();

                // Check each child condition for duplication
                for (const [index, child] of mainObj.ChildCondition.entries()) {
                    const childConditionKey = `${child.Field}-${child.Condition}-${child.ConditionText}`;
                    // Check if the child condition matches the parent condition
                    const parentConditionKey = `${mainObj.Field}-${mainObj.Condition}-${mainObj.ConditionText}`;
                    if (childConditionKey === parentConditionKey) {
                        return { conditionMismatch: `${index} ${i} Child condition in main object ${i + 1} matches the parent condition.` };
                    }

                    // Check if the child condition has been seen before (duplicate check)
                    if (seenChildConditions.has(childConditionKey)) {
                        return { conditionMismatch: `${index} ${i} Child condition ${childConditionKey} is duplicated in main object ${i + 1}.` };
                    }

                    // Add the child condition to the set of seen conditions
                    seenChildConditions.add(childConditionKey);
                }
            }

            for (let j = 0; j < mainObjects.length; j++) {
                if (i !== j) {
                    const otherMainObj = mainObjects[j];
                    const otherMainObj1 = mainObjects[i];                    

                    if ((!otherMainObj.Logic && !otherMainObj1.Logic) &&
                        mainObj.Field === otherMainObj.Field &&
                        mainObj.Condition === otherMainObj.Condition &&
                        mainObj.ConditionText === otherMainObj.ConditionText
                    ) {
                        return { conditionMismatch: `${j} Main object ${i + 1} has matching properties with main object ${j + 1}.` };
                    }
                }
            }
        }
        return null;
    };
}

make this more efficient major performance issue

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.