Home > other >  template variable to `FormControl`
template variable to `FormControl`

Time:06-03

I'm trying figure out, is a simple way to use template variable to access FormControl in FormGroup to get shorter form ? I have example like below, this is working - i always use that long format, but it annoys me.

<form [formGroup]="form">
    <mat-form-field>
        <mat-label>Field</mat-label>
        <input type="text" matInput formControlName="field">
        <mat-error *ngIf="form.get('field').hasError('required')">
            Email is <strong>required</strong>
        </mat-error>
        <mat-error *ngIf="form.get('field').hasError('otherError')">
           ...
        </mat-error>
    </mat-form-field>
</form>

Thinking about shorter form, but it doesn't work:

<form [formGroup]="form">
    <mat-form-field>
        <mat-label>Field</mat-label>
        <input type="text" matInput formControlName="field" #fieldRef>
        <mat-error *ngIf="fieldRef.hasError('required')">
            ...
        </mat-error>
        ...
    </mat-form-field>
</form>

I need to replace multiple form.get(...) calls with local variable. Anybody helps ?

CodePudding user response:

I can't think of a neat way around it, but I can think of a couple ways to do it differently. Maybe something suits your taste:

#1 Use object property access instead of get:

<form [formGroup]="form">
    <mat-form-field>
        <mat-label>Field</mat-label>
        <input type="text" matInput formControlName="field">
        <mat-error *ngIf="form.field.hasError('required')">
            Email is <strong>required</strong>
        </mat-error>
    </mat-form-field>
</form>

#2 Use the matInput directive to access the control:

<form [formGroup]="form">
    <mat-form-field>
        <mat-label>Field</mat-label>
        <input type="text" matInput formControlName="field" #field="matInput">
        <mat-error *ngIf="field.ngControl.hasError('required')">
            Email is <strong>required</strong>
        </mat-error>
    </mat-form-field>
</form>

#3 Access it from the TS

export class FormExampleComponent {
  readonly field = new FormControl();

  readonly form = new FormGroup({ field: this.field });
}
<form [formGroup]="form">
    <mat-form-field>
        <mat-label>Field</mat-label>
        <input type="text" matInput formControlName="field">
        <mat-error *ngIf="field.hasError('required')">
            Email is <strong>required</strong>
        </mat-error>
    </mat-form-field>
</form>

Besides all this, you can also think of creating your own form directive which extends from the angular one. With which you may be able to do something like:

<mat-error *myError="'required'">
  Email is <strong>required</strong>
</mat-error>

But that might be outside the scope of this question :)

CodePudding user response:

your must add in your component.ts a function that return the form control

get f(): { [key: string]: AbstractControl } {
return this.form.controls;
 }

and use this in your component.html to acess to the errors using the name of formcontrol.

*ngIf="submitted && f.filed.errors"
  • Related