What could be the reason for the form value object being devoid of any content

I am seeking help to understand how to write a custom validator for a reactive form.

Here is the component code:

private form: FormGroup;

  ngOnInit() {
    const this_ = this;

    this.form = new FormGroup({
      'email':      new FormControl(null, [Validators.required, Validators.email]),
      'password':   new FormControl(null, [Validators.required, Validators.minLength(6)]),
      'password2':  new FormControl(null, [Validators.required, Validators.minLength(6), this_.comparePasswords]),
      'name':       new FormControl(null, [Validators.required]),
      'agree':      new FormControl(false, [Validators.requiredTrue])
    });
  }

  comparePasswords(c: FormControl) {
    console.log(c);

    const hashStr = Md5.hashStr(c.value.password);
    const hashStr2 = Md5.hashStr(c.value.password2);

    console.log(hashStr, hashStr2);

    return (hashStr === hashStr2) ? null : {
      comparePasswords: {
        valid: false
      }
    };
  }

All necessary imports are included. Upon page load, the browser console immediately displays the form object with null values.

I am facing an issue in implementing the check within the function comparePasswords().

Error message displayed on console:

ERROR TypeError: Cannot read property 'password' of null

Check out live example here

Answer №1

Replace null with an empty string ""

this.form = new FormGroup({
  'email':      new FormControl("", [Validators.required, Validators.email]),
  'password':   new FormControl("", [Validators.required, Validators.minLength(6)]),
  'password2':  new FormControl("", [Validators.required, Validators.minLength(6), this_.comparePasswords]),
  'name':       new FormControl("", [Validators.required]),
  'agree':      new FormControl(false, [Validators.requiredTrue])
});

Answer №2

In addition to setting the initial value as null, your custom validator is assigned to the formcontrol, meaning it only receives the formcontrol password2, and not the entire formgroup.

To address this issue, it would be beneficial to implement the custom validator at the formgroup level or create a nested formgroup specifically for the passwords with the validator applied there. This approach ensures that changes in any input within the form do not trigger the validator unnecessarily. By applying the validator at the formgroup level, you can efficiently check both inputs simultaneously.

Construct your form like this:

constructor(private fb: FormBuilder) { }

ngOnInit() {
  this.form = this.fb.group({
    password:   ['', [Validators.required, Validators.minLength(6)]],
    password2:  ['', [Validators.required, Validators.minLength(6)]],
  },{validator: this.comparePasswords});
}

Your custom validator function should resemble the following:

comparePasswords(c: FormGroup) {
  const hashStr = Md5.hashStr(c.controls.password.value);
  const hashStr2 = Md5.hashStr(c.controls.password2.value);
  return (hashStr === hashStr2) ? null : { notSame: true };
}

You have the option to compare just c.controls.password.value and c.controls.password2.value. However, since you are utilizing Md5, those values are used here. Additionally, note that an object containing a custom error message, such as notSame, is returned if the passwords do not match.

To display the error message, you can use the following code:

<div *ngIf="form.hasError('notSame')">Passwords do not match!</div>

View your updated StackBlitz

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

Is there a way to retrieve the initial item of a JSON array from an HTML document using Angular 2?

Within the src/assets/ directory, I have a json file called product.json with the following structure: [ { "images": "http://openclipart.org/image/300px/svg_to_png/26215/Anonymous_Leaf_Rake.png", "textBox": "empty", "comments": "empty" }, { "i ...

The utilization of *ngTemplateOutlet for conditional rendering is experiencing issues when used within a formGroup

Developed a reusable form input designed to be displayed within a form either as part of a parent formGroupName or independently as a regular input control. The code implementation is: child.component.html: <ng-container *ngIf="hasFormGroup; then f ...

Exploring advanced routing concepts in Angular 2

I have a challenge in setting up routing in angular 2 with the following scenario home.component: @RouteConfig([ { path: '/', name: 'Home', component: HomeComponent }, { ...

Enhancing DOM Elements in a React Application Using TypeScript and Styled-Components with Click Event

I've been working on an app using React, Typescript, and styled components (still a beginner with typescript and styled components). I'm trying to create a simple click event that toggles between which of the two child components is visible insid ...

Conceal optional navigation bar options once a user has logged in - utilizing Angular 8

I need assistance with hiding certain links in my navbar once a user has logged in. Below are the current navbar menus: <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav ml-auto"> <li class="nav ...

How to handle an empty data response in Angular 2's HTTP service

My ASP.NET web API has a simple method with the following test results: $ curl localhost:5000/Api/GetAllQuestions [{"questionId":0,"value":"qqq","answers":[{"answerId":25,"value":"qwerty"}]}] However, I am encountering an issue in my Angular 2 HTTP serv ...

Unexpected error in boot.ts file in Angular 2

I am currently experimenting with various folder arrangements for Angular 2. When attempting to launch a local server, I encounter the following error: Uncaught SyntaxError: Unexpected token < Evaluating http://localhost:3000/prod/app/TypeScript/bo ...

A guide to setting a file size limit for image uploads (e.g. limiting to 2MB) using Angular

We are currently working on implementing a maximum size limit of 2mb for images using ng2-file-upload. Below is the code snippet: uploader: FileUploader = new FileUploader({ url: URL, disableMultipart: true }); ... ... OnFileSelected(event) { ...

Error: This property is not available on either 'false' or 'HTMLAudioElement' types

When working with React (Next.js) using hooks and typescript, I encountered an issue while trying to create a reference to an Audio element. The error message I received was: Property 'duration' does not exist on type 'false | HTMLAudioEleme ...

Angular - Evaluating the differences between the object model and the original model value within the view

To enable a button only when the values of the 'invoice' model differ from those of the initial model, 'initModel', I am trying to detect changes in the properties of the 'invoice' model. This comparison needs to happen in th ...

Exploring the fusion of different interfaces and props in React using typescript

I have designed an interface as shown below, representing the "base button". export interface ButtonProps { backgroundColor?: Colors, children?: React.ReactNode | JSX.Element, style?: CSSProperties, disabled?: boolean, onClick?: () => ...

Retrieving the selected date from mat-datepicker into a FormControl

When creating a POST request to an API, I encountered an issue with the mat-datepicker field as it throws an error when inside the ngOnInit() call (since nothing is selected yet). Other fields like name, email, etc. work fine, but extracting a value from t ...

Stop the observable interval in Angular when the route changes

I initiated an interval in an Angular component, but the requests are still being made even when I navigate to a different route. How do I halt the interval? //function that returns an observable getAllPolls() { return Observable.interval(2000).swit ...

Unable to determine all parameters for Modal: (?, ?, ?)

import { Component, Inject } from '@angular/core'; import { NavController, Modal } from 'ionic-angular'; import { PopupPage } from '../../components/modal/modal.page'; @Component({ templateUrl: 'build/pages/spot/spot. ...

Unresponsive display on both 'Ionic development application' and 'physical mobile device'

As a newbie to Ionic, I recently delved into the world of Ionic 4 by following the guidance provided in the Ionic 4 documentation. After setting up my project using ionic start myApp sidemenu --type=angular, I noticed that everything ran smoothly on my bro ...

Is it possible for me to listen to an AngularJS event using regular JavaScript, outside of the Angular framework?

Is it possible to listen to an event triggered in AngularJS using regular JS (outside of Angular)? I have a scenario where an event is being emitted using RxJS in Angular 2. Can I observe that event from pure JS? Here's some example pseudo code: imp ...

Ways to verify the identity of a user using an external authentication service

One of my microservices deals with user login and registration. Upon making a request to localhost:8080 with the body { "username": "test", "password":"test"}, I receive an authentication token like this: { "tok ...

Avoid Angular 6 router from taking precedence over routes set in Express Server

What is the best way to ensure that Angular routing does not conflict with routes from an Express Node Server? In my Express server, I have set up some routes (to node-RED middleware) as follows: server.js // Serve the editor UI from /red app.use(settin ...

What is the process for exporting a class and declaring middleware in TypeScript?

After creating the user class where only the get method is defined, I encountered an issue when using it in middleware. There were no errors during the call to the class, but upon running the code, a "server not found" message appeared. Surprisingly, delet ...

Navigational menu routing with AngularJS2 using router link paths

Currently, I am working on developing a navigation menu using angularJS2. Here is the snippet from my app.component.ts: import {provide, Component} from 'angular2/core'; import {APP_BASE_HREF, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, HashLocati ...