Short version: The submit post button only gets data that has been changed, even though the input fields have values (that are loaded). Why is not getting the loaded values ?
Long version:
So I have this form in Angular that has a bunch of input fields that have values {{sight?.name}}
, ie. it gets the values when it loads the component from a getService.
Here is a part of the html (entire page is on StackBlitz):
...
<div class="form-group sight-edit-name">
<label class="purple-text" for="sightName">Name:</label>
<input type="text" class="form-control" name="name" id="sightName" ngModel value="{{sight?.name}}">
</div>
...
This is working fine, it shows the form with the correct data when the component loads:
Now the Save button is a submit button:
<button type="submit" class="btn btn-save" (click)="onSubmitEdit(sightFormEdit.value, sight.id)">Save</button>
that calls the following function:
onSubmitEdit(value: any, sightid: any) {
//value is form, sightid is the id of current sight
console.log("You have edited form and changed to this:", value);
//call sight servise that edits the data
this.sightService.editSight(value, sightid).subscribe((res: any) => {
console.log(res);
});
}
This calls the servise that edits the data. This work fine when everything in the form is changed.
editSight(sight, sightId): Observable<any> {
let sightEditId = this.sightEdit + sightId;
return this.http.post(sightEditId, sight);
}
If you don't change a form input field, and submit the data, only the data that has been changed will be changed/submitted. It doesn't get the values that are loaded on the page.
Example: You enter a sight and edit just the name and hit "Save". When you open the same sight ONLY the name will appear, the other values were not sent.
Entire page can be found here: https://stackblitz.com/edit/angular-dsqbf3
Angular form, neither reactive or template driven forms care about [value]
. They only cares what are set in the form controls, and currently you aren't setting any values to the form controls. If you want to bind values to your form in template-driven forms, you need to bind the data with either one-way or two-way binding. Currently you are registering your form controls together with name
attribute and ngModel
, but no value are set using that method. So as said, bind your variable to the forms, for example:
<input name="name" [(ngModel)]="sight.name">
If your sight
is coming async, you can switch to one-way-binding in the form, where you can use the safe navigation operator:
<input name="name" [ngModel]="sight?.name">
DEMO with latter: StackBlitz
Also we usually set the submit function on the form tag itself, and we can omit the click function from the button, since buttons by default are of type submit
inside form tags.
Also it's completely worth it to check out Reactive Forms!