Enhance the validation of multiple fields in Angular through asynchronous AbstractControl in groupForm

Ensuring the validity of a component is crucial. A valid component is defined by its unique brand, designation, type, reference, supplierId, and familyId. The challenge arises when one or more of these attributes are not unique. For example, if I'm editing the "type" field and then change the "reference" field to something else, the component remains invalid until I also update the "reference" field. How can I resolve this issue? Thank you for your assistance.

Below is my form setup:

  this.componentDetailForm = new FormGroup({
    familyId: new FormControl(0, {
      validators: [Validators.required, Validators.min(1)],
      asyncValidators: [this.uniqueComponentValidator.bind(this)]
    }),
    brand: new FormControl('', {
      validators: [Validators.required],
      asyncValidators: [this.uniqueComponentValidator.bind(this)]
    }),
    type: new FormControl('', {
      validators: [Validators.required],
      asyncValidators: [this.uniqueComponentValidator.bind(this)]
    }),
    designation: new FormControl('', {
      validators: [Validators.required],
      asyncValidators: [this.uniqueComponentValidator.bind(this)]
    }),
    case: new FormControl(''),
    reference: new FormControl('', {
      validators: [Validators.required],
      asyncValidators: [this.uniqueComponentValidator.bind(this)]
    }),
    voltage: new FormControl(0, [Validators.required, Validators.min(0)]),
    amperage: new FormControl(0, [Validators.required, Validators.min(0)]),
    power: new FormControl(0, [Validators.required, Validators.min(0)]),
    supplierId: new FormControl(0, {
      validators: [Validators.required, Validators.min(1)],
      asyncValidators: [this.uniqueComponentValidator.bind(this)]
    }),
    price: new FormControl(0, [Validators.required, Validators.min(0)]),
    minimumQuantity: new FormControl(0, [Validators.required, Validators.min(0)]),
  }) 

Below is the validator code:

  private uniqueComponentValidator(control: AbstractControl): Observable<ValidationErrors | null> {

    this.getFormValidationErrors();
    this.component.brand = this.fc.brand.value;
    this.component.designation = this.fc.designation.value;
    this.component.type =  this.fc.type.value;
    this.component.reference = this.fc.reference.value;
    this.component.supplierId = Number(this.fc.supplierId.value);
    this.component.familyId = Number(this.fc.familyId.value);

    return this.componentService.checkComponentIsUnique(this.component).pipe(map((data) => !data ? ({ componentExists: data }) : null));
  }

Illustrating the problem visually, imagine I update the "Type" field last. The form remains invalid because the brand, designation, type, reference, supplierId, and familyId are not unique. Then, if I change the "Reference" field, the component should be valid, but it's not because the last modified field was "Type."

https://i.sstatic.net/yMGwJ.png

https://i.sstatic.net/sIkQW.png

Answer №1

It seems like your question could use a bit more clarity. Without any specific context or playground to work with, providing a precise answer might be difficult. However, here are some key points that might shed some light on your query.

FormControl instances can be updated using various FormHooks available in the Angular documentation. You can explore them further here:

https://angular.io/api/forms/AbstractControl#updateOn

Additionally, a FormControl can exist in three validation states - valid (when all validators pass), invalid (if even one validator fails), and pending (while async validators are being checked).

One thing to note is that async validators update form controls without altering memory references, which may not trigger change detection. This is particularly challenging when using the "OnPush" change detection strategy. For a practical demonstration of this issue, you can refer to the following example:

https://stackblitz.com/edit/angular-ivy-paseta?file=src/app/app.component.ts

I hope these insights prove helpful in addressing your query!

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

`Warning: The alert function is not working properly in the console error

I am currently working on integrating otp functionality into my Ionic 3 project. I am facing an issue where I am able to receive the otp, but it is not redirecting to the otp receive page due to a specific error. Below is the console error that I am encou ...

The data type 'StaticImageData' cannot be converted to type 'string'

I've hit a roadblock with interfaces while working on my NextJS and TypeScript project. I thought I had everything figured out, but I'm encountering an issue with the src prop in my Header component. The error messages I keep receiving are: Typ ...

Utilizing React with Typescript to access specific props

I am a newcomer to React and TypeScript and I am facing a challenge while trying to enhance an existing component by creating a wrapper around it. The issue I am encountering is related to adding my custom values to the properties. My goal is to extend th ...

M.E.A.N - Suite for setting up and defining backend boundaries consisting of MongoDB, Express.js, Angular2, node.js

Seeking knowledge on how the frameworks and platforms Angular 2 and Express.js collaborate in the 'mean' approach is my main query. I am interested in understanding where the client-side ends and the server-side begins. After delving into this t ...

What could be the reason behind the frequent appearance of multiple calls in Fiddler upon initiating a SignalR connection

As I set up a signalr connection from my angular front-end to an Asp.Net Core back-end, multiple calls are being made when starting the connection. The issue arises with the first call not completing, which poses a problem for our end-to-end tests. Attemp ...

The 'push' property is not found within the 'Control' type

I am attempting to create an array that contains arrays within it. This array is intended for a dynamic form functionality, where the user can add a new section and push the array of control fields to the main array. Angular2 then generates this dynamical ...

How to create an Ion-select element with dynamic options in Ionic 2?

Currently, I am working on an application in Ionic 2 and I am facing a challenge with adding ion-select options dynamically. Below is the snippet of my code: <ion-select [(ngModel)]="classifications" (ngModelChange)="updateSelectedValue($event)"> & ...

Stringified HTML code showcased

When working with Angular, I have encountered an issue where I am calling a function inside an .html file that returns a string containing a table element. My goal is to convert this string into HTML code. I attempted to use [innerHtml]: <p [innerHtml ...

Strange compilation error encountered with ng-packagr due to Angular @Input inheritance

Encountering a perplexing error message in Angular 7 while working with @Input inheritance. The error message seems illogical because I have 1 mandatory @Input and 2 optional @Input, so things should align... Error: Directive MyComponent, Expected 2 argum ...

A guide on automatically focusing on a Material UI Formik form TextField using React and TypeScript

I'm attempting to automatically focus my textField, but the 'autoFocus' attribute only seems to work after I submit the form and add a value. If no values are added (i.e. when opening the miui modal for the first time), the autoFocus does no ...

Retrieving the necessary data from my object to perform a sum calculation in angular

Having trouble retrieving an attribute from an array in my code. In my .ts file, I am fetching data from my backend endpoint like this: export class PostFeedComponent implements OnInit { data: any = {}; constructor(private http: HttpClient) { t ...

Service stub in Angular containing static properties

I am faced with a challenge in my service that requires the use of APP_INITIALIZE to set a static property value. Another service within my system depends on this property, so I need to stub this service with the static value. However, using provide is n ...

What is the most effective method for structuring JSON data that is utilized by a single-page application (SPA)?

A colleague and I are collaborating on a single page application (built in React, but the framework used isn't crucial; the same query applies to Angular as well). We have a database with 2 interconnected tables: Feature Car Both tables are linked ...

Error: The selected module is not a valid top-level option

I am facing an issue while using the babel-loader. I have removed all irrelevant code and just kept the error-related portion. What could be causing this problem? module.exports = merge(baseWebpackConfig, { ... module: { rules: [ ...

When an import is included, a Typescript self-executing function will fail to run

Looking at this Typescript code: (()=> { console.log('called boot'); // 'called boot' })(); The resulting JavaScript is: (function () { console.log('called boot'); })(); define("StockMarketService", ["require", "exp ...

Ways to determine the current active tab in React are:

Currently, I am facing an issue with my code involving two tabs. Upon clicking on the second tab, I want to display a specific message. However, I am struggling to determine when the second tab is selected. The main problem lies in the fact that the selec ...

Unable to attach to 'leafletOptions' as it is unrecognized as a property of 'div'

It seems like I keep encountering this problem, which is often resolved by adjusting import statements. Right now, my imports look like this: import { LeafletModule } from 'node_modules/@asymmetrik/ngx-leaflet'; import * as L from 'leaflet& ...

The value produced by the interval in Angular is not being displayed in the browser using double curly braces

I am attempting to display the changing value on the web page every second, but for some reason {{}} is not functioning correctly. However, when I use console.log, it does show the changing value. Here is an excerpt from my .ts code: randomValue: number; ...

When using TypeScript with custom components as children in React, the `type` returned by React.Children is a string representing the function

It might sound a bit odd, or maybe I'm completely off track here. While going through some articles and React documentation on getting children and identifying specific child components using React.Component.map(), I ran into an issue with my custom c ...

Create a custom navigation system for ng-bootstrap tabset using manual controls

Currently, when I click on the "Client" tab, the content opens. Similarly, when I click on the "Rate card" tab, the rate card content opens. However, the navigation does not work when I use the arrows at the bottom. How can I enable navigation for the ar ...