I'm working on an Angular form where I need to patch an object to a FormControl in ngAfterViewInit. However, I'm encountering an issue when trying to patch an object. Here's a simplified version of my code:
My HTML Code
<form [formGroup]="filterForm">
<div>
<mat-form-field fxFlex.lt-sm="auto">
<mat-label>Action Type</mat-label>
<mat-select formControlName="actionType">
<mat-option *ngFor="let s of actionTypeFilter" [value]="s">
{{ s.Name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</form>
My TypeScript Code
actionTypeFilter = [
{Name: 'All', Key: "All"},
{Name: 'Allow', Key: 300201},
{Name: 'Deny', Key: 300202},
];
ngOnInit() {
this.filterForm = this.formBuilder.group({
actionType: ['', Validators.required],
});
}
ngAfterViewInit() {
this.filterFormControls.actionType.patchValue({Name: 'All', Key: "All"});
}
get filterFormControls() { return this.filterForm.controls; }
The Problem: When I attempt to patch an object value to the FormControl in ngAfterViewInit, it doesn't work. However, if I modify the HTML to use the Key as the value, like this:
<mat-option *ngFor="let s of actionTypeFilter" [value]="s.Key"> {{ s.Name }} </mat-option>
this.filterFormControls.actionType.patchValue("All");
It works correctly, but the issue is when I console the value of actionType it will give only the Key value but i want full object of selected item.
I want to patch the entire object (e.g., {Name: 'All', Key: 'All'}) to the FormControl while keeping the original HTML structure. How can I achieve this?
You can use compareWith
to perform the equality check for the select using the key, so we can select the entire object using this method.
compareFn(o1: any, o2: any) {
return o1.Key === o2.Key;
}
<form [formGroup]="filterForm">
<div>
<mat-form-field>
<mat-label>Action Type</mat-label>
<mat-select formControlName="actionType" [compareWith]="compareFn">
<mat-option *ngFor="let s of actionTypeFilter" [value]="s">
{{ s.Name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</form>
{{filterForm.value | json}}
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import {
Validators,
ReactiveFormsModule,
FormGroup,
FormBuilder,
FormControl,
} from '@angular/forms';
import { CommonModule } from '@angular/common';
/** @title Simple form field */
@Component({
selector: 'form-field-overview-example',
templateUrl: 'form-field-overview-example.html',
styleUrl: 'form-field-overview-example.css',
standalone: true,
imports: [
MatFormFieldModule,
MatInputModule,
MatSelectModule,
ReactiveFormsModule,
CommonModule,
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FormFieldOverviewExample {
filterForm = new FormGroup<any>({});
actionTypeFilter = [
{ Name: 'All', Key: 'All' },
{ Name: 'Allow', Key: 300201 },
{ Name: 'Deny', Key: 300202 },
];
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.filterForm = this.formBuilder.group({
actionType: ['', Validators.required],
});
}
ngAfterViewInit() {
this.filterFormControls.actionType.patchValue({ Name: 'All', Key: 'All' });
}
compareFn(o1: any, o2: any) {
return o1.Key === o2.Key;
}
get filterFormControls() {
return this.filterForm.controls;
}
}