I have a component used to display some data (i,e first name, last name, phone ....etc) from the api. In order to perform CRUD operation specially update operation,.
As in below image:
I am facing an issue, when I click SAVE button even the data present in the input field(i,e phone). It's is still showing the warning messages(i,e mat-error). As in below image:
Below is my component code
HTML
<form [formGroup]="editForm">
<div>
<mat-form-field>
<input matInput placeholder="First Name" formControlName="firstname" required>
<mat-error *ngIf="editForm.controls.firstname.hasError('required')">
Please enter first name
</mat-error>
</mat-form-field>
</div>
<div>
<mat-form-field class="example-full-width">
<input matInput placeholder="Last Name" formControlName="lastname" required>
<mat-error *ngIf="editForm.controls.lastname.hasError('required')">
Please enter last name
</mat-error>
</mat-form-field>
</div>
<div>
<mat-form-field class="phone-number">
<input matInput placeholder="Phone Number" formControlName="phonenumber" required>
<mat-error *ngIf="editForm.controls.phonenumber.hasError('required')">
Please enter phone number
</mat-error>
<mat-error *ngIf="editForm.controls.phonenumber.hasError('pattern')">
Please enter a valid phone number
</mat-error>
</mat-form-field>
</div>
<div class="btn-sec">
<button mat-flat-button type="button" >Cancel</button>
<button mat-flat-button type="submit" (click)="onEditForm()">Save</button>
</div>
<form>
TS
import{ Component, Inject, Input, OnInit, ViewChild } from '@angular/core';
import{ FormBuilder, FormControl ,FormGroup, Validators}fro'@angular/forms';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
import {IContact } from 'src/app/models/app.models';
@Component({
selector: 'wsd-update-customer',
templateUrl: './wsd-customer.component.html',
styleUrls: ['./wsd-customer.component.css'],
})
export class EditCustomerComponent implements OnInit {
public editForm: FormGroup;
constructor(@Inject(MAT_DIALOG_DATA) public data: IContact,
private fb: FormBuilder,
public dialog: MatDialog) {}
public ngOnInit(): void {
this.editForm = this.fb.group({
firstname: [ null, [Validators.required],
lastname: [null, [Validators.required],
phonenumber: [null, [Validators.required, Validators.pattern('[0-9]+')]],
});
this.editForm.get('firstname').setValue(this.data.firstName);
this.editForm.get('lastname').setValue(this.data.lastName);
this.editForm.get('phonenumber').setValue(this.data.phoneNumbers[0].number);
}
public onEditForm(): void {
this.markAsDirty(this.editForm);
}
private markAsDirty(group: FormGroup): void {
group.markAsDirty();
for (const i in group.controls) {
group.controls[i].markAsDirty();
}
}
}
models.ts file
export interface IContact {
firstName: string;
lastName: string;
phoneNumbers: IPhoneNumber[];
}
export interface IPhoneNumber {
type: string;
number: string;
}
JSON
{
"firstName": "Adaline",
"lastName": "Danat",
"phoneNumbers": [
{
"type": "Home",
"number": "+62 342 886 8201"
},
{
"type": "Business",
"number": "+63 704 441 1937"
},
{
"type": "Unknown",
"number": "+63 530 693 2767"
}
],
}
Updated Photo
Updated Stckblitz link
You can do with the combination of FormGroup
and FormControl
where FormGroup accept an object of AbstractControl
Class.
So if you are using FormGroup then it accepts the parameter called controlsConfig
which describes:
@param controlsConfig A collection of child controls. The key for each child is the name under which it is registered
So just define the FormGroup with FormControls and add the validation and default value as to the particular Control:
this.editForm = this.fb.group({
firstname: new FormControl([null, [Validators.required]]),
lastname: new FormControl([null, [Validators.required]]),
phonenumber: new FormControl([null, [Validators.required, Validators.pattern('[0-9]+')]]),
});
EDIT:
To assign the value of formControl in a p
, span
that is except input type, there are three ways to do this
1) With using Two-way data binding on data itself like:
<p>{{data.email}}</p>
2) By using FormControl:
<p>{{editForm.value.email}}</p>
but for this, you have to define a FormControl in the TS file and use setValue to assign the value.
email: new FormControl([null]) // define a control in the group
this.editForm.get('email').setValue(this.data.email); // set value from data object
3) You use the FormContol with readonly
attribute
<mat-form-field class="example-full-width">
<input matInput placeholder="Email" formControlName="email" readonly>
</mat-form-field>