Reputation: 6871
I have an update component I want to only send the changed form values to some backend update endpoint. For some reason if I update only one form input the rest of the values appear. I had implemented a way to check empty form values and remove them from the payload object shown below in .ts file
which works but now I want to only detect changed form values & only send them. Which convenient method should I use to resolve this?
TS File
this.form = this.fb.group({
business_name: new FormControl(''),
business_activity: new FormControl(''),
business_id: new FormControl(''),
pin_number: new FormControl(''),
activity_code: new FormControl(''),
po_box: new FormControl(''),
town: new FormControl(''),
physical_address: new FormControl(''),
plot_number: new FormControl(''),
contact_person_name: new FormControl(''),
contact_person_phone: new FormControl(''),
applicantName: new FormControl(''),
sub_county_name: new FormControl(''),
ward_name: new FormControl(''),
applicantPhone: new FormControl(''),
licenseActivity: new FormControl(''),
fee: new FormControl(''),
});
onClickUpdate(){
const payload = this.form.value;
// Remove empty string
Object.keys(payload).forEach((key) => (payload[key] === '') && delete payload[key]);
console.log(JSON.stringify(payload))
}
HTML FILE
<form [formGroup]="form" class="add-new-license">
<div class="controls-container row">
<mat-form-field>
<input
type="text"
formControlName="business_name"
matInput
placeholder="Business Name"
[(ngModel)]="license.business.business_name"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="business_id"
placeholder="Business ID"
[(value)]="license.business.business_id"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="pin_number"
placeholder="Pin Number"
[(value)]="license.business.pin_number"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="po_box"
placeholder="Po Box"
[(value)]="license.business.po_box"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="town"
placeholder="Town"
[(value)]="license.business.town"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
formControlName="physical_address"
matInput
placeholder="Physical Address"
[(value)]="license.business.physical_address"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="sub_county_name"
placeholder="SubCounty"
[(value)]="license.business.sub_county_name"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="ward_name"
placeholder="Ward"
[(value)]="license.business.ward_name"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="plot_number"
placeholder="Plot Number"
[(value)]="license.business.plot_number"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="contact_person_phone"
placeholder="Phone"
[(value)]="license.contact_person_phone"
/>
</mat-form-field>
<mat-form-field>
<input
type="text"
matInput
formControlName="contact_person_name"
placeholder="Contact Person Name"
[(value)]="license.contact_person_name"
/>
</mat-form-field>
<!--
<mat-form-field>
<input type="text" matInput placeholder="Applicant Name" formControlName="applicantName">
</mat-form-field> -->
<!-- <mat-form-field id="business-name">
<input type="text" matInput placeholder="Applicant Phone" formControlName="applicantPhone">
</mat-form-field> -->
<br />
<mat-form-field matTooltip="Select license activity">
<!-- <input type="text" matInput placeholder="License Activity" formControlName="licenseActivity"> -->
<mat-label style="color: black">License Activity</mat-label>
<mat-select formControlName="licenseActivity">
<!-- <mat-option>None</mat-option> -->
<mat-option
id="schedule-options"
*ngFor="let category of liquorCategories"
[value]="category.id"
matTooltip="{{ getCategoryToolTipData(category.name) }}"
>
{{ category.name }}</mat-option
>
</mat-select>
<div
*ngIf="submitted && f.licenseActivity.errors"
class="invalid-feedback"
>
<div *ngIf="f.licenseActivity.errors.required">
License Activity is required
</div>
</div>
</mat-form-field>
<mat-form-field matTooltip="select only liquor application fee.">
<mat-label style="color: black">Fee</mat-label>
<mat-select formControlName="fee">
<mat-option *ngFor="let fee of fees" [value]="fee.id">
{{ fee.description }}: {{ fee.amount }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="row" id="submit-btn-section">
<button
mat-raised-button
(click)="onClickUpdate()"
id="submit-button"
matTooltip="submit information"
>
UPDATE LICENSE
</button>
</div>
</form>
Upvotes: 3
Views: 1358
Reputation: 920
getUpdatedValue(form: any) {
var changedValues = {};
Object.keys(form.controls)
.forEach(key => {
let currentControl = form.controls[key];
if (currentControl.dirty) {
if (currentControl.controls)
changedValues[key] = this.getUpdatedValue(currentControl);
else
changedValues[key] = currentControl.value;
}
});
return changedValues;
}
hope it will usefull for all !
Upvotes: 1
Reputation: 933
You can bind events to each and every single control. You can also get the 'pristine' property from a control.
So a good idea would be to (for example) catch the changed event of the form and check each control for the pristine
property. When pristine
is true, the value is not changed. When false, the value IS changed.
You can use the form to loop through its controls so you can pretty much do this in an automated fashion.
Upvotes: 1