4

I have a custom input component, just a cover for regular html input tag. Here is a usage example:

  <form [formGroup]="formGroup">
    <my-input [title]="Some title" formControlName="name"></my-input>
  </form>

And related component contains:

  formGroup: FormGroup = new FormGroup({
    name: new FormControl('', Validators.required),
  });

I managed to access FormControl instance from within my-input component using this approach, now what I want to do, is to add an asterisk to my-input title if it is required.

The question is - is it possible to access list of validators so I can distinguish required validator among them?

P.S. Surely I can put required attribute on the element itself

<my-input ... required></my-input>

But I want use reactive forms.

5
  • Use NG_VALIDATORS Commented Oct 24, 2019 at 7:12
  • Why don't you set up another property among <my-input [title]="Some title" [setRequired]="true" formControlName="name"></my-input> and get in child using @Input() setRequired: boolean. In html <span *ngIf="setRequired">*</span> Commented Oct 24, 2019 at 7:21
  • @varman I just don't want to move validators from component class to template, it feels more reasonable for me to keep the logic inside class Commented Oct 24, 2019 at 7:25
  • Have you implemented ControlValueAccessor to use formControlName on child? Commented Oct 24, 2019 at 8:01
  • @varman sure I did, though, I don't think this makes any difference for the case Commented Oct 24, 2019 at 9:42

2 Answers 2

4

There is the same issue open in github for a while now (so it seems you are mostly out of luck).

https://github.com/angular/angular/issues/13461

You can see solutions like the one below (thanks mtinner from github) but there is nothing official

  export const hasRequiredField = (abstractControl: AbstractControl): boolean => {
    if (abstractControl.validator) {
        const validator = abstractControl.validator({}as AbstractControl);
        if (validator && validator.required) {
            return true;
        }
    }
    if (abstractControl['controls']) {
        for (const controlName in abstractControl['controls']) {
            if (abstractControl['controls'][controlName]) {
                if (hasRequiredField(abstractControl['controls'][controlName])) {
                    return true;
                }
            }
        }
    }
    return false;
};

You'll see that most people try to solve the same problem as you.

Hope this helps!

Sign up to request clarification or add additional context in comments.

1 Comment

Athanasios, thank you for the advice. Haven't seen the issue!
-1

You can do like this

<span "formGroup.controls['name'].errors?.required>*</span>

1 Comment

This will hide the asterisk if a user put something in the input, this is not an expected behaviour and bad practice in terms of UX. Thanks for the suggestion though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.