I have this in my template:
<input type="button" value="add" (click)="addEnvVar()"/>
<div *ngFor="let envVar of application.env_vars">
<input type="text" name="key" [(ngModel)]="envVar.key">
<input type="text" name="value" [(ngModel)]="envVar.value">
</div>
The code behind addEnvVar()
:
this.application.env_vars.push({key:'', value:''});
When the component is initialized, there is one object inside env_vars
and it is rendered just fine (the <input>
fields are populated). After I click 'add', I can see in console that there are indeed two objects inside env_vars (the second is the 'empty' object I just added), and in the view there are indeed two <div>
s for each envVar
, but all 4 <input>
fields are empty.
What am I doing wrong?
UPDATE
I think the problem is that when ngFor
produces more than one div
, the inputs in each div
all get the same hard-coded name
attribute (in my case - "key" and "value"), and the value is somehow attached to that. I changed name="key"
to name="key_{{i}}"
(i
is a template variable holding the ngFor
index property).
Question is, is this the way to go? Or am I still missing something?
The culprit with errors like this is mostly likely the default trackBy
function which tracks the references. Even if the data hasn't changed, but the references change, it will tear down the DOM and re-build it, meaning all data inside the input fields will be cleared.
trackBy(index) { return index }
*ngFor="let envVar of application.env_vars; trackBy: trackBy"
Unfortunately I cannot test it without a reproduction. However, JB Nizet's comment is right and you should follow this advice; this is a task more suited for reactive forms, and not template forms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With