I'm a bit late to the game but I think this could be solved by using a Pipe. The answers above solve your problem but there is a small caveat. By directly using a method/getter in your template, this function is executed every change detection run as stated in this article. It might not be a performance issue in your short example but might be a problem in larger forms.
My solution
By using a pure Pipe the check on the provided control is fired once the input value to the Pipe has changed. I've added the ControlRequiredPipe
to the AppModule
providers
and declarations
parts. When the pipe is added to the providers
part, it can be used in a Component
TypeScript class as well. I've included this behavior in the OnSubmit
function in the AppComponent
.
Stackblitz example
AppComponent
:
<form [formGroup]="form" (submit)="onSubmit()">
Control: <strong *ngIf="form.get('control') | controlRequired">*</strong>
<input type="text" formControlName="control">
<button>Submit</button>
</form>
import { Component } from "@angular/core";
import { FormGroup, FormControl, Validators } from "@angular/forms";
import { ControlRequiredPipe } from "./control-required.pipe";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
form: FormGroup = new FormGroup({
control: new FormControl(null, [
Validators.required,
Validators.minLength(8)
])
});
constructor(private controlRequiredPipe: ControlRequiredPipe) {}
onSubmit() {
alert(
`The required state of the FormControl is: ${this.controlRequiredPipe.transform(
this.form.get("control")
)}`
);
}
}
ControlRequiredPipe
:
import { Pipe, PipeTransform } from "@angular/core";
import { AbstractControl } from "@angular/forms";
@Pipe({
name: "controlRequired"
})
export class ControlRequiredPipe implements PipeTransform {
public transform(control: AbstractControl): boolean {
// Return when no control or a control without a validator is provided
if (!control || !control.validator) {
return false;
}
// Return the required state of the validator
const validator = control.validator({} as AbstractControl);
return validator && validator.required;
}
}
AppModule
:
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { AppComponent } from "./app.component";
import { ControlRequiredPipe } from "./control-required.pipe";
@NgModule({
imports: [BrowserModule, FormsModule, ReactiveFormsModule],
declarations: [AppComponent, ControlRequiredPipe],
providers: [ControlRequiredPipe],
bootstrap: [AppComponent]
})
export class AppModule {}