Ensuring equality of values in Angular2 reactive forms

I'm currently working on an Angular2 Reactive form that requires users to confirm their email address. You can check out the plunker for reference here

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { User } from './signup.interface';

@Component({
selector: 'signup-form',
template: `
    <form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user">
    <label>
        <span>Full name</span>
        <input type="text" placeholder="Your full name" formControlName="name">
    </label>
    <div class="error" *ngIf="user.get('name').touched && user.get('name').hasError('required')">
        Name is required
    </div>
    <div class="error" *ngIf="user.get('name').touched && user.get('name').hasError('minlength')">
        Minimum of 2 characters
    </div>
    <div formGroupName="account">
        <label>
        <span>Email address</span>
        <input type="email" placeholder="Your email address" formControlName="email">
        </label>
        <div
        class="error"
        *ngIf="user.get('account').get('email').hasError('required') && user.get('account').get('email').touched">
        Email is required
        </div>
        <label>
        <span>Confirm address</span>
        <input type="email" placeholder="Confirm your email address" formControlName="confirm">
        </label>
        <div
        class="error"
        *ngIf="user.get('account').get('confirm').hasError('required') && user.get('account').get('confirm').touched">
        Confirming email is required
        </div>
    </div>
    <button type="submit" [disabled]="user.invalid">Sign up</button>
    </form>
`
})
export class SignupFormComponent implements OnInit {
  user: FormGroup;
  constructor() {}
  ngOnInit() {
    this.user = new FormGroup({
    name: new FormControl('', [Validators.required, Validators.minLength(2)]),
      account: new FormGroup({
        email: new FormControl('', Validators.required),
        confirm: new FormControl('', Validators.required)
      })
    });
  }
  onSubmit({ value, valid }: { value: User, valid: boolean }) {
    console.log(value, valid);
  }
}

I'm looking for a way to validate and show an error when the two email fields do not match.

Could someone guide me on how to implement this behavior using reactive forms in Angular2?

I came across a tutorial illustrating a similar approach with template-driven forms here, but I'm specifically interested in achieving this using reactive forms.

Answer №1

I have successfully implemented password matching using reactive forms. To adapt this for email validation, simply replace the password validator with an email validator. Both data types are strings, so everything else remains the same. Remember to include the password match error handling in the email validation as well.

app.module.ts

To utilize reactive forms, add the following code snippet to your app.module.ts file:

import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    import { AppComponent } from './app.component';
    @NgModule({
      imports: [
        BrowserModule,
        FormsModule,
        ReactiveFormsModule,
     ],
    declarations: [
    AppComponent
     ]
  providers: [],
  bootstrap: [
    AppComponent
   ]
  })
export class AppModule {}

app.component.ts

import { Component, OnInit } from '@angular/core';
import template from './add.component.html';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { matchingPasswords } from './validators';
@Component({
    selector: 'app',
    template
})
export class AppComponent implements OnInit {
    addForm: FormGroup;
    constructor(private formBuilder: FormBuilder) {
    }
    ngOnInit() {

    this.addForm = this.formBuilder.group({
            username: ['', Validators.required],
            email: ['', Validators.required],
            role: ['', Validators.required],
            password: ['', Validators.required],
            password2: ['', Validators.required] }, 
          { validator: matchingPasswords('password', 'password2') <-- replace args with email_1 and email_2
        })
    };

addUser() {
        if (this.addForm.valid) {
            var addUser = {
                username: this.addForm.controls['username'].value,
                email: this.addForm.controls['email'].value,
                password: this.addForm.controls['password'].value,
                profile: {
                    role: this.addForm.controls['role'].value,
                    name: this.addForm.controls['username'].value,
                    email: this.addForm.controls['email'].value
                }
            };
          console.log(addUser);// addUser contains all form values, you can store it as needed
            this.addForm.reset();// reset form values to null 
        }
    }  
}

app.component.html

<div>
  <form [formGroup]="addForm">
   <input type="text" placeholder="Enter username" formControlName="username" />
   <input type="text" placeholder="Enter Email Address" formControlName="email"/>
   <input type="password" placeholder="Enter Password" formControlName="password" />
   <input type="password" placeholder="Confirm Password" name="password2" formControlName="password2"/>
   <div class='error' *ngIf="addForm.controls.password2.touched">
    <div class="alert-danger errormessageadduser" *ngIf="addForm.hasError('mismatchedPasswords')">                                  Passwords do not match
  </div>
</div>
<select name="Role" formControlName="role">
    <option value="admin" >Admin</option>
    <option value="Accounts">Accounts</option>
    <option value="guest">Guest</option>
</select>
<br/>
<br/>
<button type="submit" (click)="addUser()"><span><i class="fa fa-user-plus" aria-hidden="true"></i></span> Add User </button>
</form>
</div>

validators.ts

export function matchingPasswords(passwordKey: string, confirmPasswordKey: string) {
    return (group: ControlGroup): {
        [key: string]: any
    } => {
        let password = group.controls[passwordKey];
        let confirmPassword = group.controls[confirmPasswordKey];

        if (password.value !== confirmPassword.value) {
            return {
                mismatchedPasswords: true
            };
        }
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for simulating http.ServerResponse and http.IncomingMessage when using express.static

Testing my own route handlers has always been straightforward, but I recently encountered an issue while trying to test express's static handler. Despite my best efforts, I can't seem to figure out why it's stalling. There must be a callback ...

Encountering a CORS issue when attempting to establish a connection with S3 from a Rails application utilizing TextureLoader

I've been struggling with this issue for a while now. Despite searching on various search engines, I haven't made much progress. I have a script that loads a texture onto a sphere. var loader = new THREE.TextureLoader(); //allow cross origin ...

Modify the script to manage the closing of one modal while simultaneously opening a different one

Looking for help with adjusting a script to close the current Modal and open a new one on button click, all while utilizing a reusable modal framework loading PartialViews. I feel like I'm overlooking something crucial but can't quite figure out ...

The output of the Node.js crypto.pbkdf2 function may not match the result obtained from CryptoJS.PBKDF

Currently, I am utilizing PBKDF2 on both the frontend with CryptoJS and the backend with Node.js. Despite using the identical salt, algorithm, number of iterations, and password, the derived keys are turning out to be different. Below is the code snippet ...

Using PrimeNG's DataTable component, you can easily modify the class or style of a

Is it possible to dynamically add a class to each individual cell in a table based on the data values? <p-dataTable [value]="invoices" tableStyleClass="table-invoices"> <p-column field="status" header="Status" styleClass="mini status"> ...

What is the best way to transform an Observable<Observable<HttpEvent<any>>> into an Observable<HttpEvent<any>> within the Angular AuthInterceptor service?

export class AuthInterceptor implements HttpInterceptor { constructor(private usersService: UsersService){} intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return this.usersService ...

Deactivating AngularJS debug information in a gulp / typescript production compilation

What is the most effective approach to disabling debug data in a gulp production build? The recommended method for disabling debug data is: myApp.config(['$compileProvider', function ($compileProvider) { $compileProvider.debugInfoEnabled(false ...

Is there a method in TypeScript to make an enum more dynamic by parameterizing it?

I've defined this enum in our codebase. enum EventDesc { EVENT1 = 'event 1', EVENT2 = 'event 2', EVENT3 = 'event 3' } The backend has EVENT1, EVENT2, EVENT3 as event types. On the UI, we display event 1, event 2, a ...

Retrieve the contents of a nearby text file and store them in a variable

I've run into a frustrating issue that I just can't seem to solve. My goal is simple - fetch a local text file and store its contents in a variable. I've tried using different methods like the fetch API, $.get, and Ajax, but no matter what I ...

Calculating the factorial of a number using the reduce function

I've been working on a function to find the factorial of an integer and then reducing the array containing factorials (multiplying each element). For instance: factor(5) >>> [1, 2, 3, 4, 5] >>> 1 * 2 * 3 * 4 * 5 >>> 120 v ...

Which is the better option for data storage: JSON files or MySQL database?

I am currently developing a project that utilizes the vis.js JavaScript framework to showcase a visual network of various categories. There are approximately 2000 categories available for selection, each with a substantial amount of associated data. I am ...

Is it possible to use Ajax post with localhost on Wamp server?

Looking to execute a basic POST function using Ajax on my localhost WAMP server. Here's the code I have: function fill_table() { var xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari ...

What could be causing the itemClicked() function to malfunction intermittently in Ionic2 / Angular2?

The issue at hand One common problem experienced with Angular's (click) functionality is that it may not work properly when <div> tags are utilized. In certain situations, multiple clicks might be required. I encountered the same problem mysel ...

Elevate your Material UI Avatar with an added level of

Attempting to give a MUI Avatar component some elevation or shadow according to the documentation provided here. <Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" /> Enclosing the Avatar within a paper or Card element increases the size o ...

Removing items from a list with Node.js and Express using Mongoose

Having trouble deleting elements after retrieving them from the database with mongoose. I'm unsure how to select a specific element in the list for deletion. My app features a user list with corresponding ages. Check out my userview.ejs (updated afte ...

Enjoy watching a video by simply hovering over the highlighted words

I am looking to implement a function where the video plays when hovering over highlighted words and pauses when the mouse moves away. However, I am currently only able to get the video to autoplay upon hover, not the highlighted words. Any assistance on th ...

"Encountering issue with the find() function following a successful outcome

I am encountering some issues with my extension. In the following code snippet, I am using a find() function to extract data from an external page: $.ajax({ url: 'http://www.subspedia.tv/traduzioni.php', success: function(data) { ...

Deciphering JSON string without quotation marks

What's the most straightforward way to parse an unquoted JSON string? For instance, if I have something like this: {property1:value1, property2:value2} Using the following code will result in an error: JSON.parse(badJSONString); This is because ...

Sending an array to the routes/index.js file from the app.js in Node.js using Express 4

Is there a way to pass an array of objects to the routes middleware in order to dynamically render the view based on the passed variables? Here is the current setup I am working with: app.js var index = require('./routes/index'); ARRAY = [obj ...

Ways to resolve the issue of the React.js landing page authentication running prior to the JWT cookie being established

I've been working on developing a blog post application using React, and now I'm in the process of integrating authentication and authorization into the app using JWT tokens (utilizing the Jsonwebtoken npm library) with a backend in Node.js. The ...