0

I'm implementing my own components for my Angular project. I'm trying to be smart about implementing validation messages.

My current implementation has multiple boolean inputs for "required", "invalidFormat" and such.

What I want to do is, user form control validations inside my custom inputs. So I want something like this:

<div *ngIf="formcONTROL.errors?.['required']">
      This field is required
</div>

And I want that inside the custom component and for multiple validations, such as format, minLength etc.

But I want to do that without having a form control input. My custom input class implements ControlValueAccessor so it works inside a reactive form but I want to know is there any way to access the control that is bound to the component I'm working on?

Also is that considered best practice? It seems to me like the best approach to error handling. I just want to provide formControlName and let the component deal with validation under the hood.

I tried implementing using boolean input fields and it works, but it requires of me to do a lot of code repetition such as this:

<custom-input type="email"
formControlName="email"
[label]="t('email.title')"
[requiredError]="formGroup.controls['email'].errors?.['required']"
[formatError]="formGroup.controls['email'].errors?.['email']"
[required]="true">
</custom-input>

<custom-input type="password"
formControlName="password"
[label]="t('password.title')"
[requiredError]="formGroup.controls['password'].errors?.['required']"
[required]="true">
</custom-input>

And I would like to just pass formControlName and that would be enough for handling validation

zvocs
  • 1
  • 2
  • if in your constructor inject the ngControl you have the control: `constructor(private control:NgControl){}`. BTW, I feel that a better aproach use viewProvider like in this [SO](https://stackoverflow.com/questions/74771994/parent-is-not-passing-form-values-to-cva-child-form-group/74801573#74801573). If only want to makes an input with labels, errors, etc it's not necesary implements ControlValueAccessor – Eliseo Mar 24 '23 at 12:50

1 Answers1

0

How about passing the FormControl object to your child component like this:

<form [formGroup]="form">
  <custom-input [control]="form.controls['theControlName']">
  </custom-input>
</form>

Then your custom-input component would look like this:

import {Component, Input} from '@angular/core';
import {FormControl} from '@angular/forms';

@Component({
  selector: 'custom-input',
  templateUrl: './input.component.html',
  styleUrls: ['./input.component.scss']
})
export class InputComponent {
  @Input() control: FormControl;
}

And in the template you can check for errors on the FormControl:

<input [formControl]="control">
<div *ngIf="control.errors?.['required']">
      This field is required
</div>
  • That is my second option. This can get ugly especially in formArrays. That's why I was wondering if there's a direct access from the component to the form control. But I will do as you said if nothing else. – zvocs Mar 23 '23 at 18:51