Reputation: 179
Upon submitting the form, I want to capture only the values of the fields that have been changed.
Using the valueChanges function on the form captures every field of the form and it can't be traversed as an array as I've tried to do in my code below.
I'm not sure of any other way the 'before and after' values of a form can be compared and stored where only the fields that were changed are stored.
export class JobEditComponent implements OnInit {
jobNumber: any;
jobs: any[];
jobToEdit: Job;
job: any;
brands: Brand[];
jobForm: FormGroup;
bsConfig: Partial<BsDatepickerConfig>;
isFormReady: any;
jobId: number;
existingValues: string[] = [];
changedValues: string[] = [];
constructor(private route: ActivatedRoute,
private jobService: JobService,
private fb: FormBuilder,
private router: Router,
private alertify: AlertifyService) { }
ngOnInit() {
this.route.params.subscribe(params => {
this.jobNumber = +params['id'];
});
this.jobService.getJobToEdit().subscribe((jobs: Job[]) => {
this.jobs = jobs;
}, error => { console.log('error');
}, () => {
this.jobToEdit = this.jobs.find(j => j.id === this.jobNumber);
this.editJobForm();
this.onChanges();
});
this.getBrands();
this.bsConfig = {
containerClass: 'theme-blue'
};
}
onChanges(): void {
this.jobForm.valueChanges.subscribe(val => {
if (this.existingValues != null) {
this.existingValues = val;
}
});
}
editJobForm() {
this.jobForm = this.fb.group({
jobNumber: [this.jobToEdit.jobNumber, Validators.required],
item: [this.jobToEdit.item, Validators.required],
status: [this.jobToEdit.status, Validators.required],
orderedBy: [this.jobToEdit.orderedBy, Validators.required],
orderDate: [this.jobToEdit.orderDate, Validators.required],
quantity: [this.jobToEdit.quantity, Validators.required],
unitPrice: [this.jobToEdit.unitPrice, Validators.required],
lineValue: [this.jobToEdit.lineValue, Validators.required],
dpAp: [this.jobToEdit.dpAp, Validators.required],
eta: [this.jobToEdit.eta, Validators.required],
detailStatus: [this.jobToEdit.detailStatus, Validators.required],
comments: [this.jobToEdit.comments, null]
}, ); this.isFormReady = true;
}
updateJob() {
this.alertify.confirm('Are you sure you want save changes?', () => {
this.jobId = this.jobToEdit.id;
this.jobToEdit = Object.assign({}, this.jobForm.value);
this.jobService.editJob(this.jobToEdit, this.jobId).subscribe(() => {
this.alertify.success('Update successful');
**for (let i = 0; i < this.existingValues.length; i++) {
if (this.jobToEdit[i] !== this.existingValues[i]) {
this.changedValues[i] = this.jobToEdit[i];
}
}**
console.log(this.changedValues);
}, error => {
this.alertify.error(error);
}, () => {
this.router.navigate(['/home']);
});
});
}
}
Upvotes: 2
Views: 3329
Reputation: 15442
Try this for your loop:
// declare changedValues as key -> val object (not array)
changedValues: { [key: string]: any } = {};
Object.keys(this.existingValues).forEach(i => {
if (this.jobToEdit[i] !== this.existingValues[i]) {
this.changedValues[i] = this.jobToEdit[i];
}
}
UPDATE
the same loop using for (key in object)
syntax as proposed by @Alex:
for (let key in this.existingValues) {
if (this.jobToEdit[key] !== this.existingValues[key]) {
this.changedValues[key] = this.jobToEdit[key];
}
}
Upvotes: 1
Reputation: 73357
You can check the values on submit, instead of using valueChanges
, so if your form would look like this:
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
field1: [this.values.field1],
field2: [this.values.field2],
field3: [this.values.field3]
})
}
you can on submit check the values of the properties and see if they match:
// 'values' is 'myForm.values'
onSubmit(values) {
let changed = {};
for (let ctrl in values) {
if(values[ctrl] !== this.values[ctrl]) {
changed[ctrl] = values[ctrl];
}
}
console.log(changed);
}
Here's a
Upvotes: 0