Mastery over the manipulation of manipulations

As I work on validating my forms using mat-errors and hasErrors, everything runs smoothly until I encounter the need for another control within an "inner" form group. Here is what I mean:

prozessPersonenzuordnungenForm = new FormGroup({
    person: new FormGroup({
      firmenbezeichnung: new FormControl(),
      nameC: new FormControl('', [Validators.required]),
      briefanrede: new FormControl('x'),
    }),
  });

I am trying to access the validation for person.nameC. I am currently using this function:

public hasError = (controlName: string, errorName: string) => {
    return this.prozessPersonenzuordnungenForm.controls[controlName].hasError(
      errorName
    );
  };

The issue lies in the fact that with this function, I can only reach the person FormGroup and not the nameC formControl. Thus, I require a "deeper control."

This is how my HTML is structured:

<mat-error *ngIf="hasError('nameC', 'required')">Please enter a person!</mat-error>

I have also attempted using person.nameC in the HTML, but it did not work either. What would be a suitable approach to access my inner FormControl with the hasError function?

Answer №1

Given the simplified structure of your controls property being an object:

controls = {
    person: {
       nameC: {
         hasErrors: err => bool
       }
    }
}

You cannot access

controls["person.nameC"]
directly as there is no such property and dot notations are not automatically converted for nested property accessing.

How you handle this scenario is up to you. One approach is to parse the dot-separated strings, split them, and iterate over them to access the nested properties.

For example, if you split the string "person.nameC" into an array using ., you will get

arr = [ "person", "nameC" ]

Now let's look at the algorithm:

let property = controls;

We start with the root property - the entire control object, and iteratively go deeper:

property = property[ arr[0] ]

This translates to

property = property["person"]
, resulting in:

property = {
    nameC: {
       hasErrors: err => bool
    }
}

Repeat the process:

property = property[ arr[1] ]

Which becomes

property = property["nameC"]
, yielding:

property = {
    hasErrors: err => bool
}

This is the desired outcome.

Instead of manual steps like above, you can loop through it:

let property: any = this.prozessPersonenzuordnungenForm.controls;
controlName.split('.').forEach(propertyKey => property = property[propertyKey]);

return property.hasError(errorName);

Answer №2

Thanks a lot for all the help, but I actually discovered a much simpler method!

Here is the solution that worked for me:

public checkForError = (controlName: string, deepControlName:string,  errorName: string) => {
    return this.prozessPersonenzuordnungenForm.controls[controlName].get(deepControlName)?.hasError(errorName);
  };

Now, I can easily implement it like this:

<mat-error *ngIf="checkForError('person', 'nameC', 'required')"> </mat-error>  

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

What is the process of applying arguments to a class constructor automatically?

In my code, there is an ES6 class called User and a global function named map(): class User { constructor(public name: string) {} } const map = <T, R>(project: (value: T) => R) => {} Instead of the usual way of calling map like this: map ...

Is there a tool in Node.js to set up a new project, similar to the scaffolding feature in Visual Studio for C# projects

Is there a way to efficiently create a node.js project with TypeScript and Express, and embed an SPA client using React and Redux templates written in TypeScript as well? Is there a scaffolding tool available to streamline this process, similar to the ea ...

Service error: The function of "method" is not valid

In one of my Angular 2 applications, I have a class that contains numerous methods for managing authentication. One particular method is responsible for handling errors thrown by the angular/http module. For example, if a response returns a status code o ...

Ensure that the database is properly configured before running any test suites

Currently, I am facing the challenge of seeding my database with all the necessary resources required to successfully test my API. These tests are spread across multiple files. Is there a method that will allow me to fully seed the database before any tes ...

Utilizing Observable Data in Angular 4 TypeScript Components

Looking to extract and assign a JSON value obtained from an API into a variable. Here is an example: TS this.graphicService.getDatas().subscribe(datas => { this.datas = datas; console.log(datas); }); test = this.datas[0].subdimensions[0].entr ...

Duplicate NgRx Effects found during loading process

My feature module is quite simple; it offers services and imports its own stats fragment as a feature: @NgModule({ imports: [ CommonModule, StoreModule.forFeature('alarms', alarmsReducer, { initialState: alarmsInitialState }), Effe ...

Exploring the capabilities of UIGrid in conjunction with TypeScript DefinitelyTyped has been a

I've noticed that the latest release of UI Grid (RC3) has undergone significant architectural changes compared to nggrid. I am encountering some problems with the definitelytyped files for nggrid because they are from a different version. Will there ...

Setting a value to an optional property of an inherited type is a simple task that can

export interface CgiConfiguration { name: string, value?: string } export interface CgiConfigurationsMap { [configurationName: string]: CgiConfiguration } const createCGI = <T extends CgiConfigurationsMap>(configurations: T) => configur ...

Utilizing Typescript's type inference within a universal "promisify" function

Unique Context Not long ago, I found myself delving into the world of "promisification" while working on a third-party library. This library was packed with NodeJS async functions that followed the callback pattern. These functions had signatures similar ...

The first click does not trigger the update for the md-autocomplete

After successfully implementing md-autocomplete in my Angular4 app, I encountered a problem where the options do not show up when the list is first clicked, unlike in the demo. The options only appear once a selection is made. Here is the HTML code: &l ...

aiplafrom struggles to establish a customer using Vite alongside Vue and TypeScript

I'm currently experimenting with Gemini Pro on Vite + Vue + TS, but I encountered an issue when attempting to create an instance of PredictionServiceClient. The error message displayed is Uncaught TypeError: Class extends value undefined is not a cons ...

What is the proper way to effectively utilize TS typings when using styled-components with withComponent()?

I am struggling to understand how to use the withComponent() method of a StyledComponent in a Typescript setting. I have a basic styled component that I want to apply to a React component. However, the Typescript compiler is flagging an issue with props no ...

Utilizing dynamic translation ID with Angular's $localize feature

Angular 9 introduces a new feature with @angular/localize that allows code translation directly from typescript. While the official documentation is lacking, I discovered some helpful tips in this post. $localize`:@@my-trans-unit-id:` // This method works ...

The server.js file is malfunctioning and unable to run

Here are the versions I am using in my application: "node": "7.2.1", "npm": "4.4.4" "@angular/cli": "1.4.9", "@angular/core": "4.4.6" After deploying my application on Heroku, it built successfully. However, when I try to run it, I encounter an "Applica ...

"Production mode is experiencing a shortage of PrimeNG(Angular) modules, while they are readily accessible in development

I've been diligently working on an Angular application that heavily relies on PrimeNG as the UI component framework. Initially, I had no issues deploying my app with Angular version 9 and PrimeNG version 8. However, a while ago, I decided to upgrade t ...

How can I trigger a function after all nested subscriptions are completed in typescript/rxjs?

So I need to create a new user and then create two different entities upon success. The process looks like this. this.userRepository.saveAsNew(user).subscribe((user: User) => { user.addEntity1(Entity1).subscribe((entity1: EntityClass) => {}, ...

What is the reasoning behind TypeScript including both `void` and `undefined` in its type system?

When working with TypeScript, it is possible to specify that a function returns void: function fn1(): void { // OK } function fn2(): void { // Error return 3; } Additionally, you have the option to annotate a function as returning undefined: func ...

Looking for a regular expression to verify if the URL inputted is valid in TypeScript

After conducting thorough research, I discovered that none of the suggested URLs met my criteria, prompting me to raise a new query. Here are my specific requirements: * The URL may or may not include 'http' or 'https' * The URL can co ...

Access denied: Authentication with Google Sign-In in Firebase is not permitted for this domain

I'm encountering difficulties with enabling Firebase Google sign-in for a custom domain. Strangely enough, it seems to work perfectly fine when the app is running on localhost. I have already added the custom domain to the list of Authorized domains w ...

execute script upon changes to the DOM of the embedded vendor component

Incorporating a vendor component into MyComponent. @Component({ selector: 'my-component', template: `<vendor-component></vendor-component>` }) export class MyComponent { constructor() { } } Looking to execute some jQuery ope ...