Custom validation for Angular template-driven form fails to properly update the state of the form

I am currently working on creating a custom validator for a template-driven form. The validator I have created (shown below) works perfectly for field-level validation, but I am facing an issue where the validation state for the entire form is not updating. This means that even when all the controls are valid, the form tag still displays class="ng-invalid".

Interestingly, when I remove the phoneValidator from the control in my template, everything functions as expected.

I suspect that the problem might be related to the registerOnValidatorChange method defined in the interface. Although I haven't implemented this method in my custom validator, I am unsure of how to utilize it effectively:

export interface Validator {
    validate(c: AbstractControl): ValidationErrors | null;
    registerOnValidatorChange?(fn: () => void): void;
}

Any insights or suggestions on this issue would be greatly appreciated. Thank you!

file: phonevalidator.directive.ts:

import { Directive, forwardRef } from '@angular/core';
import { NG_VALIDATORS, AbstractControl, ValidationErrors, Validator, FormControl } from '@angular/forms';

@Directive({
  selector: '[validPhoneNumber]',
  providers: [
    { provide: NG_VALIDATORS, useExisting: PhoneValidatorDirective, multi:     true }
  ]
})
export class PhoneValidatorDirective implements Validator {

  validate(control: FormControl): ValidationErrors | null {
    return PhoneValidatorDirective.validatePhone(control);
  }

  static validatePhone(control: FormControl): ValidationErrors | null {

    var regEx = new RegExp(/^[1-9]\d{2}-\d{3}-\d{4}/);

    console.log("Phone validator: validating phone number.")

    var controlValue: string = control.value;

    console.log(regEx.exec(controlValue));

    if (!(regEx.exec(controlValue))) {
      // Return error if phone number is not valid
      console.log('returning false');
      return { phoneNumber: false };
    } else {
      // If no error, return null
      console.log('returning true');
      return { phoneNumber: true };
    }

  }
}

Answer №1

It appears that this question was already answered in a similar post about Angular 2 form status is always invalid with custom validation for ng-select control.

The key takeaway is that the validator should return null when the control is valid, rather than 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

Utilize ng-content to access the component provider within a child component

I have been utilizing the ngx-mapbox-gl library, found at this link. This library includes a component called "mgl-map", which allows users to add child layer components that will render on the map. My objective is to create a parent component that contai ...

Encountering a service call error during the execution of Angular 2 unit tests using Jasmine

Struggling with testing an angular service, my TypeScript code seems correct but I keep getting an error in my test cases for "this.someFunction.show()" not being a function, even though it exists in my actual service. Here is what I'm attempting to d ...

Error TS[2339]: Property does not exist on type '() => Promise<(Document<unknown, {}, IUser> & Omit<IUser & { _id: ObjectId; }, never>) | null>'

After defining the user schema, I have encountered an issue with TypeScript. The error message Property 'comparePassword' does not exist on type '() => Promise<(Document<unknown, {}, IUser> & Omit<IUser & { _id: Object ...

Ionic - Smooth horizontal tab scrolling for sorted categories

Currently, we are developing a web/mobile application that includes horizontal scroll tabs to represent Categories. While this feature works well on mobile devices, it requires additional functionality for web browsers. Specifically, we need to add two arr ...

Angular toolbar permanently positioned at the top of the screen

My custom toolbar, along with other components, is present in the app I'm working on. In the app.component, the structure looks something like this: <app-toolbar> </app-toolbar> <main> <a [routerLink]="['/login/en&a ...

Incorporating a CSS Module into a conditional statement

Consider the following HTML structure <div className={ `${style.cell} ${cell === Player.Black ? "black" : cell === Player.White ? "white" : ""}`} key={colIndex}/> Along with the associated CSS styles .cell { ...

Adding properties to a class object in Javascript that are integral to the class

Recently, I've been contemplating the feasibility of achieving a certain task in JavaScript. Given my limited experience in the realm of JavaScript, I appreciate your patience as I navigate through this. To illustrate what I am aiming for, here' ...

What is the best way to determine the type of a static property in a TypeScript class?

I have a utility class containing various static methods: export default class MyHelper { private constructor() {} private static privateMethod() {} public static publicHelperMethod() {} } In my React component, I am using the publicHelperMet ...

Developing web applications with Angular 6, C#, and MVC involves dynamically generating and returning JsonResults from the controller in the form of

I have been working on exporting datasets to Excel within an Angular 6 application. To achieve this, I have been utilizing XLSX and File-save functionalities as outlined in the following example: https://medium.com/@madhavmahesh/exporting-an-excel-file-in- ...

Union types discriminate cases within an array

Creating a union type from a string array: const categories = [ 'Category A', 'Category B' ] as const type myCategory = typeof categories[number] myCategory is now 'Category A' | 'Category B' Now, the goal is ...

Updating token (JWT) using interceptor in Angular 6

At first, I had a function that checked for the existence of a token and if it wasn't present, redirected the user to the login page. Now, I need to incorporate the logic of token refreshing when it expires using a refresh token. However, I'm enc ...

Angular application utilizes role-based approach for populating elements

I am currently developing a project that involves tightly coupling UI components with the permissions assigned to the logged-in user role. (Angular 4 for front end and Spring for backend) Upon successful login, the backend server returns a user object alo ...

"Error: The update depth has exceeded the limit while trying to use the

I've been working on implementing localStorage in NextJs using TypeScript by following this guide at , but I am encountering an error. https://i.sstatic.net/NX78a.png Specifically, the error occurs on the context provider repeatedly. Below is the c ...

Is it advisable to avoid circular imports in typescript development?

After spending 4 long hours troubleshooting a TypeScript error, I finally found the root cause. Object literal may only specify known properties, and 'details' does not exist in type 'Readonly<{ [x: `details.${string}.value`]: { value: st ...

What is the best way to inform Angular2 RC1 about updates in the DOM?

Originally inspired by a discussion on Stack Overflow, this scenario presents a simpler use case. The issue at hand is how to inform Angular2 about externally added DOM elements that contain Angular directives. For example, adding a new button with a click ...

Testing the function that relies on a service through a unit test

I'm currently working on unit testing a component. However, I encountered an issue with one of its methods that utilizes a service and is causing a 'cannot read property 'then' of undefined' error. While I understand how to call a ...

Limiting the character input in ion-textarea within Ionic 2: A step-by-step guide

In my Ionic 2 application, I need to limit user comments to less than 500 characters in a text area. What is the best way to implement this restriction? ...

Steps for resolving the error message: "An appropriate loader is required to handle this file type, but there are no loaders currently configured to process it."

I am encountering an issue when working with next.js and trying to export a type in a file called index.ts within a third-party package. Module parse failed: Unexpected token (23:7) You may need an appropriate loader to handle this file type, current ...

Error with declaring TypeScript class due to private variable

When defining a TypeScript class like this: export class myClass { constructor(public aVariable: number) {} private aPrivateVariable: number; } and trying to initialize it with the following code: let someVar: myClass[] = [{ aVariable: 3 }, { aV ...

Displaying ASP.Net Core Application on local IIS - Unable to locate content

I started a new project in Visual Studio Code by running the following command: dotnet new angular --use-local-db Afterwards, I upgraded Angular from version 8 to 10 and completed the project. To test it, I used dotnet watch run Everything was running ...