route page navigationend change based angular2 angular

page - Validación de forma angular 2 para repetir contraseña



router events subscribe angular 4 (19)

Consulte esta question respecto a los campos de comparación en el validador con angular2 . Desafortunadamente, Angular 2 cambió un poco, por lo que la solución ya no funciona. Aquí está mi código:

import {IonicApp,Page,NavController,NavParams} from ''ionic/ionic'' import {Component} from ''angular2/core'' import {FORM_PROVIDERS, FormBuilder, Validators} from ''angular2/common'' import {ControlMessages} from ''../../components/control-messages'' import {ValidationService} from ''../../services/validation-service'' @Page({ templateUrl: ''build/pages/account/register.html'', directives: [ControlMessages] }) export class RegisterPage { constructor(nav:NavController,private builder: FormBuilder) { this.nav = nav this.registerForm = this.builder.group({ ''name'' : ['''', Validators.required], ''email'' : ['''',Validators.compose([Validators.required, ValidationService.emailValidator])], ''password'' : ['''',Validators.required], ''repeat'' : ['''',this.customValidator] } ) } register() { alert(this.registerForm.value.password) } private customValidator(control) { //console.log(this.registerForm.value.password) //return {isEqual: control.value === this.registerForm.value.password} return true } }

Mi html:

<ion-content class="account"> <ion-list padding> <form [ngFormModel]=''registerForm'' (submit)=''register()''> <div class="centered"> <img class="logo" src="img/logo.png" alt=""> </div> <div class="spacer" style="height: 20px;"></div> <ion-input> <ion-label floating>Name</ion-label> <input type="text" ngControl=''name'' id=''name''> <control-messages control="name"></control-messages> </ion-input> <ion-input> <ion-label floating>Email</ion-label> <input type="email" ngControl=''email'' id=''email''> <control-messages control="email"></control-messages> </ion-input> <ion-input> <ion-label floating>Password</ion-label> <input type="password" ngControl=''password'' id=''password'' value=""> <control-messages control="password"></control-messages> </ion-input> <ion-input> <ion-label floating>Confirm Password</ion-label> <input type="password" ngControl=''repeat'' id=''repeat''> <control-messages control="repeat"></control-messages> </ion-input> <button class="calm" full type=''submit'' [disabled]=''!registerForm.valid''>Register</button> <ion-item style="background-color:transparent;border:none;"> <button class="text-button" clear item-right (click)="gotoLogin()">Have an account already, Login</button> </ion-item> </form> </ion-list> </ion-content>

Pero desafortunadamente, no puedo acceder al valor de ''contraseña'' en mi función de validación. Si descomento console.log (this.registerForm.value.password) , aparece el siguiente mensaje de error:

EXCEPCIÓN: TypeError: no se puede leer la propiedad ''valor'' de undefined

¿Alguna idea? Gracias.


Además, a partir de angular 2 rc4 con formas 0.2.0, el marcado y el atributo que llama el nombre del grupo utilizado para abarcar las entradas agrupadas es necesario para evitar errores

<div formGroupName="passwords">group input fields here... </div>


Al usar esta biblioteca ng2-validation-manager puedes hacer esto fácilmente:

this.form = new ValidationManager({ ''password'' : ''required|rangeLength:8,50'', ''repassword'' : ''required|equalTo:password'' });


Aquí está mi manera de usar validadores angulares

COMPONENTE:

import { UserModel } from ''../../settings/users/user.model''; import { AbstractControl, FormBuilder, FormGroup, Validators } from ''@angular/forms''; import { FormRequestModel } from ''../Shared/form.model''; import { Component, OnInit } from ''@angular/core''; @Component({ selector: ''app-add-user'', templateUrl: ''./add-user.component.html'', styleUrls: [''./add-user.component.scss''] }) export class AddUserComponent implements OnInit { passwordsForm: FormGroup; user: UserModel; constructor(private fb: FormBuilder) { } ngOnInit() { this.passwordsForm = this.fb.group({ inputPassword: ['''', Validators.compose([Validators.required, Validators.minLength(6), Validators.maxLength(50)])], inputPasswordAgain: [''''] }); } }

HTML:

<form class="form-horizontal" [formGroup]="passwordsForm" novalidate> <div class="form-group"> <br/> <label for="inputPassword" class="col-sm-2 control-label">Password</label> <div class="col-sm-10"> <input type="password" formControlName="inputPassword" class="form-control" id="inputPassword" placeholder="Password"> </div> </div> <div class="alert alert-danger" *ngIf="!passwordsForm.controls[''inputPassword''].valid && passwordsForm.controls[''inputPassword''].touched">Password must contain at least 6 characters!!</div> <div class="form-group"> <br/> <label for="inputPasswordAgain" class="col-sm-2 control-label">Password again</label> <div class="col-sm-10"> <input type="password" formControlName="inputPasswordAgain" class="form-control" id="inputPasswordAgain" placeholder="Password again"> </div> </div> <!-- Show div warning element if both inputs does not match the validation rules below --> <div class="alert alert-danger" *ngIf="passwordsForm.controls[''inputPasswordAgain''].touched && passwordsForm.controls[''inputPasswordAgain''].value !== passwordsForm.controls[''inputPassword''].value"> Both passwords must be equal!</div>


Bueno, busqué una respuesta sobre este tema y todos eran demasiado grandes para mi pereza, así que lo hice así. Creo que hace bien el trabajo.

Utilicé el ngModel para enlazar la contraseña y repetir la entrada de contraseña y luego he mostrado u ocultado el div con el mensaje de comparación de contraseña con el atributo [oculto] en angular 2.

<label for="usr">Password</label> <input placeholder="12345" id="password" type="text" class="form-control" [(ngModel)]="password"> <label for="usr">Repeat pasword</label> <input placeholder="12345" type="text" class="form-control" [(ngModel)]="repeatPassword"> <div [hidden]="password == repeatPassword">Passwords do not match!</div>


Encontré una solución mucho más simple. No estoy seguro si esta es la forma correcta de hacerlo, pero funciona para mí

<!-- PASSWORD --> <ion-item [ngClass]="{''has-error'': !signupForm.controls.password.valid && signupForm.controls.password.dirty}"> <ion-input formControlName="password" type="password" placeholder="{{ ''SIGNUP.PASSWORD'' | translate }}" [(ngModel)]="registerCredentials.password"></ion-input> </ion-item> <!-- VERIFY PASSWORD --> <ion-item [ngClass]="{''has-error'': !signupForm.controls.verify.valid && signupForm.controls.verify.dirty}"> <ion-input formControlName="verify" [(ngModel)]="registerCredentials.verify" type="password" pattern="{{registerCredentials.password}}" placeholder="{{ ''SIGNUP.VERIFY'' | translate }}"> </ion-input> </ion-item>

Ver

pattern="{{registerCredentials.password}}"


Encontré una solución que me hizo más feliz en cuanto a la consistencia del código y el manejo de errores:

Primero: crear una clase de validación personalizada con un método estático que realice la validación

Este método debe tener un parámetro AbstractControl que inyecte angularmente

Tenga en cuenta que pasará esto en el control ConfirmPassword, por lo que debe llamar a los padres para acceder al FormGroup. Desde allí, llama a formGroup.get (''myControl'') y obtiene los controles para la contraseña y confirma como los nombró cuando creó el grupo de formularios.

import {AbstractControl} from ''@angular/forms''; export class PasswordValidation { static MatchPassword(AC: AbstractControl) { const formGroup = AC.parent; if (formGroup) { const passwordControl = formGroup.get(''Password''); // to get value in input tag const confirmPasswordControl = formGroup.get(''Confirm''); // to get value in input tag if (passwordControl && confirmPasswordControl) { const password = passwordControl.value; const confirmPassword = confirmPasswordControl.value; if (password !== confirmPassword) { return { matchPassword: true }; } else { return null; } } } return null; } }

2do: Use su Validador de clientes al igual que usa angulares

this.registerForm = this.fb.group({ // <-- the parent FormGroup Email: ['''', Validators.required ], Username: ['''', Validators.required ], FirstName: ['''', Validators.required ], Password: ['''', [ Validators.required, Validators.minLength(6) ] ], Confirm: ['''', [ Validators.required, PasswordValidation.MatchPassword ] ] });

Angular luego agregará ''matchPassword'': verdadero a su Confirmar controla los errores exactamente como agregaría ''requerido'' verdadero cuando falta un valor


Esta es la forma más fácil que sigo. He eliminado el código que no es relevante.

Creo que esto te ayudará.

auth.component.ts, auth.component.html, auth.component.css

import { Component, OnInit, EventEmitter, Input, Output ,Directive, forwardRef, Attribute,OnChanges, SimpleChanges} from ''@angular/core''; import { NG_VALIDATORS,Validator,Validators,AbstractControl,ValidatorFn } from ''@angular/forms''; import { ActivatedRoute, Router } from ''@angular/router''; import { RegisterUser } from ''../shared/models''; @Component({ moduleId: module.id, selector: ''auth-page'', styleUrls: [''./auth.component.css''], templateUrl: ''./auth.component.html'' }) export class AuthComponent implements OnInit { userRegisterModel: RegisterUser = new RegisterUser(); constructor(private route: ActivatedRoute, private router: Router) { } ngOnInit() { this.userRegisterModel.LoginSource = ''M'';//Manual,Facebook,Google } userRegister() { console.log(this.userRegisterModel); } }

.validation { margin:0; padding-top: 1px; padding-bottom: 0px; } .validation .message { font-size: 10px; color: #de1a16; }

<form (ngSubmit)="userRegister()" #authRegisterForm="ngForm" novalidate> <div class="col-md-6 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> <label>First Name:</label> <input type="text" class="form-control" required pattern="[a-zA-Z][a-zA-Z ]+" [(ngModel)]="userRegisterModel.firstName" name="firstName" #firstName="ngModel" placeholder="Your first name"> <div style="display: flex;">&nbsp; <div [hidden]="firstName.valid || firstName.pristine" class="validation"> <div [hidden]="!firstName.hasError(''required'')" class="message">Name is required</div> <div [hidden]="!firstName.hasError(''pattern'')" class="message">Only alphabets allowed</div> </div> </div> </div> <div class="col-md-6 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> <label>Last Name:</label> <input type="text" class="form-control" required pattern="[a-zA-Z][a-zA-Z ]+" [(ngModel)]="userRegisterModel.lastName" name="lastName" #lastName="ngModel" placeholder="Your last name"> <div style="display: flex;">&nbsp; <div [hidden]="lastName.valid || lastName.pristine" class="validation"> <div [hidden]="!lastName.hasError(''required'')" class="message">Name is required</div> <div [hidden]="!lastName.hasError(''pattern'')" class="message">Only alphabets allowed</div> </div> </div> </div> <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> <label>Email:</label> <input type="text" class="form-control" required [(ngModel)]="userRegisterModel.email" name="email" pattern="^/w+([/.-]?/w+)*@/w+([/.-]?/w+)*(/./w{2,3})+$" #email="ngModel" placeholder="Your email"> <div style="display: flex;">&nbsp; <div [hidden]="email.valid || email.pristine" class="validation"> <div [hidden]="!email.hasError(''required'')" class="message">Email is required</div> <div [hidden]="!email.hasError(''pattern'')" class="message">Email format should be <small> <b>[email protected]</b> </small> </div> </div> </div> </div> <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> <label>Password:</label> <input type="password" class="form-control" required [(ngModel)]="userRegisterModel.password" name="password" #password="ngModel" minlength="6" placeholder="Your strong password" > <div style="display: flex;">&nbsp; <div [hidden]="password.valid || password.pristine" class="validation"> <div [hidden]="!password.hasError(''minlength'')" class="message">Password should be 6digit</div> <div [hidden]="!password.hasError(''required'')" class="message">Password is required</div> </div> </div> </div> <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> <label>Confirm Password:</label> <input type="password" class="form-control" required validateEqual="password" [(ngModel)]="userRegisterModel.confirmPassword" name="confirmPassword" #confirmPassword="ngModel" placeholder="Confirm your password"> <div style="display: flex;">&nbsp; <div [hidden]="confirmPassword.valid || confirmPassword.pristine" class="validation"> <div class="message">Passwords did not match</div> </div> </div> </div> <div class="col-md-12 form-group text-right" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> <button type="submit" class="btn btn-primary" [disabled]="!authRegisterForm.form.valid"> Submit form <i class="icon-arrow-right14 position-right"></i> </button> </div> </form>

registerUser.mocel.ts

export class RegisterUser { FirstName : number; LastName : string; Email: string; Password : string; }

password.match.directive.ts

import { Directive, forwardRef, Attribute } from ''@angular/core''; import { NG_VALIDATORS,Validator,Validators,AbstractControl,ValidatorFn } from ''@angular/forms''; @Directive({ selector: ''[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]'', providers: [ { provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true } ] }) export class EqualValidator implements Validator { constructor( @Attribute(''validateEqual'') public validateEqual: string) {} validate(c: AbstractControl): { [key: string]: any } { // self value (e.g. retype password) let v = c.value; // control value (e.g. password) let e = c.root.get(this.validateEqual); // value not equal if (e && v !== e.value) return { validateEqual: false } return null; } }

app.module.ts

import { ModuleWithProviders, NgModule } from ''@angular/core''; import { BrowserModule } from ''@angular/platform-browser''; import { RouterModule } from ''@angular/router''; //import { AppRoutingModule } from ''./app-routing.module''; //import { AppComponent } from ''./app.component''; //shared components import { EqualValidator} from ''./shared/password.match.directive''; @NgModule({ declarations: [ // AppComponent, //FooterComponent, // HeaderComponent, // LoginComponent, // LayoutComponent, // AuthComponent, // UserExistComponent, // HomeComponent, EqualValidator ], imports: [ // BrowserModule, // AppRoutingModule, // SharedModule ], providers: [ // ApiService, // AuthGuard, //JwtService, // UserService, // HomeAuthResolver, // NoAuthGuard, // SharedService ], bootstrap: [AppComponent] }) export class AppModule { }


Guarde la contraseña en la variable de instancia.

password = new FormControl('''', [Validators.required]);

Luego úselo en su grupo de formularios.

this.registrationForm = this.fb.group({ ''email'': ['''', [ Validators.required, NGValidators.isEmail, ] ], ''password'': this.password, ''password2'': ['''', [Validators.required, this.passwordMatch]] });

Entonces la función se ve así.

private passwordMatch() { let that = this; return (c: FormControl) => { return (c.value == that.password.value) ? null : {''passwordMatch'': {valid: false}}; } }

Sé que no es la mejor solución, ¡pero está funcionando!


He implementado un validador de coincidencia de contraseñas personalizadas para Angular 4.

Además de verificar si dos valores coinciden, también se suscribe a los cambios de otro control y vuelve a validar cuando se actualiza cualquiera de los dos controles. Siéntase libre de usarlo como referencia para su propia implementación o simplemente copiarlo directamente.

Aquí está el enlace a la solución: https://gist.github.com/slavafomin/17ded0e723a7d3216fb3d8bf845c2f30 .

Y aquí estoy proporcionando una copia del código:

match-other-validator.ts

import {FormControl} from ''@angular/forms''; export function matchOtherValidator (otherControlName: string) { let thisControl: FormControl; let otherControl: FormControl; return function matchOtherValidate (control: FormControl) { if (!control.parent) { return null; } // Initializing the validator. if (!thisControl) { thisControl = control; otherControl = control.parent.get(otherControlName) as FormControl; if (!otherControl) { throw new Error(''matchOtherValidator(): other control is not found in parent group''); } otherControl.valueChanges.subscribe(() => { thisControl.updateValueAndValidity(); }); } if (!otherControl) { return null; } if (otherControl.value !== thisControl.value) { return { matchOther: true }; } return null; } }

Uso

Así es como puede usarlo con formas reactivas:

private constructForm () { this.form = this.formBuilder.group({ email: ['''', [ Validators.required, Validators.email ]], password: ['''', Validators.required], repeatPassword: ['''', [ Validators.required, matchOtherValidator(''password'') ]] }); }

Más validadores actualizados se pueden encontrar aquí: moebius-mlm/ng-validators .


Mi solución para Angular 4.3.4, que no requiere FormGroup adicional:

  • registre un validador personalizado para la verificación repeatedPassword contraseñas si las contraseñas son las mismas
  • suscriba el controlador en password.valueChanges durante la creación del formulario y llame .updateValueAndValidity() method en repeatedPassword

Aquí hay un código:

form: FormGroup passwordFieldName = ''password'' repeatedPasswordFieldName = ''repeatedPassword'' createForm() { this.form = this.formBuilder.group({ login: ['''', [Validators.required, Validators.minLength(3), Validators.maxLength(255), Validators.email]], [passwordFieldName]: ['''', [Validators.required, Validators.minLength(6), Validators.maxLength(255)]], [repeatedPasswordFieldName]: ['''', [Validators.required, this.samePassword]] }); this.form .get(passwordFieldName) .valueChanges.subscribe(() => { this.form .get(repeatedPasswordFieldName).updateValueAndValidity(); }) } samePassword(control: FormControl) { if (!control || !control.parent) { return null; } if (control.value !== control.parent.get(passwordFieldName).value) { return {''passwordMismatch'': true} } return null; }


No creo que necesitemos un validador personalizado para contraseñas coincidentes, esto se puede lograr fácilmente usando formname.controls[''controlName''].value .

<input type="password" class="form-control" formControlName="password"> <div class="alert alert-danger" *ngIf="!userForm.controls[''password''].valid && userForm.controls[''password''].touched"> Enter valid password between 7 and 14 characters. </div> <input type="password" class="form-control" formControlName="confPassword"> <div *ngIf="userForm.controls[''confPassword''].touched"> <div class="alert alert-danger" *ngIf="userForm.controls[''confPassword''].value != userForm.controls[''password''].value"> Password do not match </div> </div>

En fileName.component.ts el control de formulario declarado como:

''password'':[null, Validators.compose([Validators.required, Validators.minLength(7), Validators.maxLength(14))], ''confPassword'':[null, Validators.required]


Recién comenzando con Angular y encontré esta solución, no sé si es una buena práctica:

// Custom password confirmation validation static matchFieldValidator(fieldToMatch:string) : ValidatorFn { return (control : AbstractControl) : { [key: string]: any;} => { let confirmField = control.root.get(fieldToMatch); return (confirmField && control.value !== confirmField.value) ? {match:false} : null; } }

De esta manera, puede hacer algo como esto al configurar las reglas de validación

this.registrationForm = fb.group({ ... password1 : ['''', [Validators.minLength(3)]], // remember to replace RegisterComponent with YOUR class name password2 : ['''', [RegisterComponent.matchFieldValidator(''password1'')]], });


Respondiendo a la persona de Zhou Hao que planteó la cuestión del debate, creo que esto es lo que estaba buscando porque me sucedió lo mismo que a usted, dijo que la variable no estaba definida y la resolvió así:

static comparePassword(control) { try { control.parent.value.password; if (control.parent.value.password == control.value) { return null; } else { return { ''invalidValue'': true }; } } catch (e) { e.message; } }


Si desea crear una directiva y usarla, vea esto

Aquí está el código completo de la directiva

import { Directive, Attribute } from ''@angular/core''; import { Validator, NG_VALIDATORS } from ''@angular/forms''; @Directive({ selector: ''[advs-compare]'', providers: [{provide: NG_VALIDATORS, useExisting: CompareDirective, multi: true}] }) export class CompareDirective implements Validator { constructor(@Attribute(''advs-compare'') public comparer: string){} validate(c: Control): {[key: string]: any} { let e = c.root.get(this.comparer); if(e && c.value !== e.value){ return {"compare": true}; } return null; } }

Para obtener más información sobre cómo usarlo, consulte http://www.advancesharp.com/blog/1226/angular-5-email-compare-password-validation-different-ways


Si está utilizando RC.5 y no puede encontrar ControlGroup, puede intentar usar FormGroup. Puede encontrar más de mi respuesta:

Angular 2 RC.5 validación de formulario para repetir contraseña


Solo quiero publicar mi solución:

this.authorizationSettings = formBuilder.group({ currentPassword: [null, Validators.compose([Validators.required, Validators.minLength(8)])], newPassword: [null, Validators.compose([Validators.required, Validators.minLength(8)])], repeatNewPassword: [null] }); this.authorizationSettings.controls.newPassword.valueChanges.subscribe(data => { if (data) { data = data.replace(/[|//{}()[/]^$+*?.]/g, ''//$&''); } this.authorizationSettings.controls.repeatNewPassword .clearValidators(); this.authorizationSettings.controls.repeatNewPassword .setValidators(Validators.compose([Validators.required, Validators.pattern(data)])); });

Primero debemos crear un grupo de formularios, luego suscribirnos al primer campo de contraseña nuevo y luego agregar validación para repetir el campo.


Veo varios problemas en tu código. Intenta utilizar this palabra clave en la función de validación y esto no corresponde a la instancia del componente. Es porque hace referencia a la función cuando la configura como una función de validación.

Además, el valor asociado con un control se puede alcanzar en la propiedad de value .

Dicho esto, creo que la forma correcta de validar sus dos campos juntos es crear un grupo y asociar un validador en él:

import { FormBuilder, Validators } from ''@angular/forms''; ... constructor(private fb: FormBuilder) { // <--- inject FormBuilder this.createForm(); } createForm() { this.registerForm = this.fb.group({ ''name'' : ['''', Validators.required], ''email'': ['''', [Validators.required, Validators.email] ], ''passwords'': this.fb.group({ password: ['''', Validators.required], repeat: ['''', Validators.required] }, {validator: this.matchValidator}) }); }

De esta manera, tendrá acceso a todos los controles del grupo y no solo a uno, y ya no necesitará usar this palabra clave ... Se puede acceder a los controls de formulario del grupo utilizando la propiedad de controls de FormGroup. FormGroup se proporciona cuando se activa la validación. Por ejemplo:

matchValidator(group: FormGroup) { var valid = false; for (name in group.controls) { var val = group.controls[name].value (...) } if (valid) { return null; } return { mismatch: true }; }

Vea esta respuesta para más detalles:

Editar

Para mostrar el error, simplemente puede usar lo siguiente:

<span *ngIf="!registerForm.passwords.valid" class="help-block text-danger"> <div *ngIf="registerForm.passwords?.errors?.mismatch"> The two passwords aren''t the same </div> </span>


¡Solución angular 4.3.3!

Puede hacerlo usando: [formGroup] , formGroupName , formControlName en html y new FormGroup , new FormControl y el método areEqual personalizado en TS

reg.component.html

<div [formGroup]="userFormPassword"> <div> <input formControlName="current_password" type="password" placeholder="Current Password"> </div> <div formGroupName="passwords"> <input formControlName="new_password" type="password" placeholder="New Password"> </div> <div formGroupName="passwords"> <input formControlName="repeat_new_password" type="password" class="form-control" placeholder="Repeat New Password"> <div class="input-error" *ngIf=" userFormPassword.controls[''passwords''].errors && userFormPassword.controls[''passwords''].errors.areEqual && userFormPassword.controls[''passwords''].controls.repeat_new_password.touched && userFormPassword.controls[''passwords''].controls.new_password.touched ">PASSWORDS do not match </div> </div> </div>

reg.component.ts

export class HomeHeaderSettingsModalComponent implements OnInit { userFormPassword: FormGroup; // ... static areEqual(c: AbstractControl): ValidationErrors | null { const keys: string[] = Object.keys(c.value); for (const i in keys) { if (i !== ''0'' && c.value[ keys[ +i - 1 ] ] !== c.value[ keys[ i ] ]) { return { areEqual: true }; } } } ngOnInit() { this.userFormPassword = new FormGroup({ ''current_password'': new FormControl(this.user.current_password, [ Validators.required, ]), ''passwords'': new FormGroup({ ''new_password'': new FormControl(this.user.new_password, [ Validators.required ]), ''repeat_new_password'': new FormControl(this.user.repeat_new_password, [ Validators.required ]) }, HomeHeaderSettingsModalComponent.areEqual) }); } }

Resultado:


Resumen

  • Activa la validación cada vez que cambia el valor del otro control.
  • Darse de baja para evitar pérdidas de memoria
  • devolver {match: true} nos permitirá verificar si un control dado tiene el error usando myControl.hasError(''match'')

Implementación

import { AbstractControl, ValidatorFn } from ''@angular/forms''; import { Subscription } from ''rxjs/Subscription''; export function matchOtherValidator(otherControlName: string): ValidatorFn { return (control: AbstractControl): { [key: string]: any } => { const otherControl: AbstractControl = control.root.get(otherControlName); if (otherControl) { const subscription: Subscription = otherControl .valueChanges .subscribe(() => { control.updateValueAndValidity(); subscription.unsubscribe(); }); } return (otherControl && control.value !== otherControl.value) ? {match: true} : null; }; }

Ejemplo

this.registerForm = formBuilder.group({ email: ['''', [ Validators.required, Validators.email ]], password: ['''', [ Validators.required, Validators.minLength(8) ]], confirmPassword: ['''', [ Validators.required, matchOtherValidator(''password'') ]] });