Accessing formControl in Angular reactive forms for custom validation purposes

I created a unique custom validator that works like this:

export function checkValidity(control: AbstractControl, shouldValidate: boolean,
                         errorDetails: { [key: string]: boolean }): null | { [key: string]: boolean } {
    const valueToCheck: string = control.value;
    if (!valueToCheck || shouldValidate) {
        return null;
    } else {
        return errorDetails;
    }
}

It's quite simple and easy to understand: It extracts the value from the form control and returns null if the value is defined or meets the given condition in a parameter, otherwise it returns an error object.


Now I want to use this custom validator on a control, but I'm not sure how to pass the current AbstractControl. I attempted something like this:

private formDataBuilder: FormBuilder = new FormBuilder();

public createForm(formData: SomeType): FormGroup {
    return this.formDataBuilder.group({
        days: [formData.days],
        ...
        useDefaultRule: [formData.useDefaultRule],
        urls: this.formBuilder.group({
            webUrl: [formData.urls.webUrl, [checkValidity(new FormControl(),
                hasWebURLPattern(new FormControl().value),
                {webUrl: true})]]
        })
    });
}

Unfortunately, this approach doesn't work. How can I correctly pass the current form control as a parameter?

Answer №1

It appears that your validation function may not have been implemented correctly.

Consider using the following approach instead:

export function validate(callback: Function, error: string): ValidatorFn {
  return (control: FormControl) => {
    return control.value && callback(control.value) ? { [error]: true } : null;
  };
}

You can apply this by using:

webUrl: ['', [validate(hasWebURLPattern, 'webUrl')]]

This method involves passing a function which will directly handle the form control's value within the validator. Additionally, providing an error string upfront helps simplify the code structure.

Keep in mind that if your callback relies on the this context, you should bind it accordingly:

webUrl: ['', [validate(hasWebURLPattern.bind(this), 'webUrl')]]

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

Error message: Angular 2 JsonpModule import not defined

Within my app.module.ts file, I have the specified code import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {JsonpModule} from '@angular/http'; import {AppComponent} from & ...

How to Retrieve a Global Variable in an Angular Template

Is there a way to access a global variable from an Angular template? let unableToAccess = false; @Component({ selector: 'app-payment', templateUrl: './buy.component.html', styleUrls: ['./buy.component.scss'] }) export ...

Create a distinct style for material inputs without relying on ng-deep, !important declarations

I am looking to customize the appearance of a material input by making it round with border radius. I found a solution that involves adding a class "custom-search" to the mat-form-field and applying the necessary styles in the global stylesheet: .custom-se ...

Is it possible to iterate through TypeScript using both keys and indexes?

Explained in detail at this link, TypeScript introduces a foreach loop: let someArray = [9, 2, 5]; for (let item of someArray) { console.log(item); // 9,2,5 } However, is there a way to access the index/key? I was thinking something along the lines of ...

Display a dropdown menu in Angular when the "@" symbol is typed into an input field

I am trying to achieve the functionality where a dropdown menu is displayed when @ is typed in the input field. The Custom Component myControl: FormControl = new FormControl(); options = [ 'One', 'Two', 'Three&ap ...

Guide to hosting a Razor partial view within Angular, without using IIS

Exploring an age-old topic on How to utilize ASP.Net MVC View .csthml as Angular View rather than .html I am seeking a similar solution but with Angular 15 and VS Code. My goal is to develop Angular components within VS Code for an ASP.NET MVC site (not W ...

Steps for storing API information in localStorage:1. Retrieve the API data

My app is running sluggish due to the excessive API calls for information retrieval. To optimize performance, I want to create a unified object containing all the data that can be shared across pages and accessed from localStorage, thus enhancing the app ...

Is it a commonly recommended method to nest fxLayout containers?

Recently, I ventured into using Angular Flex for the first time and I find myself a bit unsure about the nesting of layout containers. The issue arises when dealing with a navigation tag that triggers an angular-material sidenav opening to the left, pushin ...

There was an issue trying to access the 'img' property of an undefined value in JSON data

I have successfully generated a JSON file containing data. Through the use of a provider in Ionic 3, I have managed to fetch the data. Below is the content of the JSON file [ { "teachers": { "img":"assets/home/img.png" } ...

Utilize TypeScript Compiler (tsc) without the need for global installation via

Currently, I am tackling a project that needs to be delivered to a group of individuals. This project is written in TypeScript, requiring them to execute the command tsc for compilation. The issue arises when I run this command following the execution of ...

Modify/remove table using a popup window

My goal was to include edit and delete buttons within a table. When these buttons are clicked, a popup window opens allowing us to modify the values and then update them in the table using Angular. ...

Recursive Vue components can be implemented using typescript, allowing for

I am working on a TypeScript component that utilizes recursion: <template> <div :style="{ paddingLeft: depth * 20 + 'px' }"> <h1>Level {{ depth }}</h1> <div v-if="depth < 2"> &l ...

Factory function with type constraints and default parameter causing TS2322 error

I have a base class that requires some parameters to be passed... class BaseClass<ItemType> { // Some irrelevant parameters omitted for simplicity... constructor(__items: Iterable<ItemType>) {} } Now, I want to create a factory func ...

Tips for securely encrypting passwords before adding them to a database:

While working with Nest.Js and TypeORM, I encountered an issue where I wanted to hash my password before saving it to the database. I initially attempted to use the @BeforeInsert() event decorator but ran into a roadblock. After some investigation, I disc ...

Discover the geolocation data for post code 0821 exclusively in Australia using Google Maps Geocoding

I'm having trouble geocoding the Australian postcode 0821. It doesn't seem to reliably identify this postcode as being located within the Northern Territory, unlike 0820 and 0822 which work fine. Here's an example of what I'm doing: ...

Troubleshooting: Issues with importing Less files in TypeScript using Webpack and css-loader

I am currently working on a test project using TypeScript and Webpack. I have an index.ts file and a base.less (or base.css) file imported in the index.ts, but I am experiencing errors with the css-loader. Interestingly, everything works fine when the LESS ...

What steps are involved in setting up a sorting feature?

In order to utilize the array.sort() function, a number-returning function must be specified. Typically, it would look something like this: myArray.sort((item1, item2) => a < b); However, I am aiming for a different structure: myArray.sort(by(obj ...

Bring in jspm libraries to your project via typescript

While researching how to import jspm packages into typescript, I noticed that most examples assumed the use of SystemJS for loading and interpreting them in the browser. However, I prefer using tsc to compile commonjs modules and only import the js code, a ...

Resetting an Angular form will clear the initially selected value

My application is built using Angular 4, and I have a select element inside my reactive form setup like this: <select class="form-control" formControlName="persons"> <option value="" selected>Select default</option> <option * ...

Testing the method in Angular using Jasmine is not possible due to the presence of a spy

Within my component, I have several concrete methods: public show(summary: GridSummary) { this.resetModal(summary); this.summary.direction = this.summary.direction || 'Response'; this.title = this.getTitle(summary); this.parentId ...