I am making a directive that sets 'attr.error' through @HostBinding if the injected ngControl status is valid while listening to injected ngForm submit event.
'attr.error' is essentially passing the error state to a webcomponent (have to use), empty string = no error displayed etc. on webcomponent.
I don't really have a use for formControlName / formGroupName / formGroup as @Input({required: true}) but it would be nice to have typescript throw a fit if this directive was used on an element where these don't exist. Any idea how I can force those as required but not use them? Or any suggestions if I should do something different here. Thanks!
Here is my component which is working right now:
import { Directive, HostBinding, inject, Input, OnDestroy, OnInit } from '@angular/core';
import { ControlContainer, NgControl, NgForm } from '@angular/forms';
import { EMPTY, iif, Subscription, tap } from 'rxjs';
@Directive({
selector: '[appDynamicControlError]',
standalone: true
})
export class DynamicControlErrorDirective implements OnInit, OnDestroy{
@Input({required: true}) suppliedErrorText!: string;
@HostBinding('attr.error')
get errorText() {
return this.errorString;
}
set errorMessageSet(message: string) {
this.errorString = message;
}
private errorString = '';
private ngControl = inject(NgControl, {self: true, optional: true}) || inject(ControlContainer, {self: true});
private ngForm = inject(ControlContainer, {skipSelf: true}).formDirective as NgForm;
private submitSubscriber!: Subscription;
ngOnInit(): void {
this.submitSubscriber = iif(() => !!this.ngForm, this.ngForm.ngSubmit, EMPTY)
.pipe(
tap(() => {
if (this.ngControl.status !== 'VALID') {
this.errorMessageSet = this.suppliedErrorText;
} else {
this.errorMessageSet = '';
}})
).subscribe();
}
ngOnDestroy(): void {
this.submitSubscriber.unsubscribe();
}
}