Reputation: 1618
I have an array of strings passed as an argument to a component, inside the component I am using "each" helper to render each string in a text input. I tried the following approach.
MainComponent.hbs
<Component @model={{model}}/>
//Eg: model.list = ["Jack", "Sparrow"];
Component.hbs
<div>
{{#each this.args.model.list as |name|}}
<div>
<PaperInput @value={{ name }}
@placeholder="Enter a Name"
@onChange={{action (mut name)}}/>
</div>
{{/each}}
</div>
I am running into the error "Uncaught (in promise) Error: Assertion Failed: You can only pass a path to mut". Would really appreciate if anyone can let me know What's going wrong here.
Upvotes: 0
Views: 975
Reputation: 1618
Figured it out. Posting the full implementation for the benefit of others. I passed down the index value to component's action as suggested in Gokul's answer but ran into another problem. There was no straight forward method to change the array's value. So I used the Mutable Array's replace method do that. That again caused another problem, every time I entered a character in the text input it was chaning the array value and re rendering the list which took the focus out of the input. So in "each" helper I had to set key="@index" which tells the helper to rerender only if there is a array index change, not the value.
Component.js
@action
updateName( index, name ) {
this.args.model.list.replace(index, 1, [name]);
}
MainComponent.hbs
<Component @model={{model}}/>
Component.hbs
{{#each this.args.model.list key="@index" as |name index|}}
<div>
<PaperInput @value={{ name }}
@placeholder="Enter a Name"
@onChange={{action this.updateName index}}/>
</div>
{{/each}}
Upvotes: 1
Reputation: 1610
The value that are derived from helpers (each
in your case) cannot be mutated using mut
helper as the helpers usually don't pass down or hold the values to change the original property.
For instance,
It makes sense if we are mutating a value as below where capitalize
is a helper:
<button {{action (mut name) (capitalize name)}}>
Capitalize
</button>
however, below snippet does't fit right as helper returns the value one way!
<button {{action (mut (capitalize name)) name}}>
Capitalize
</button>
the same thing is going on with the each
helper and the looped through value cannot be mutated! This code comment might be useful for further digging.
You can change your snippet to handle the onChange
in the backing component class instead:
<div>
{{#each this.args.model.list as |name index|}}
<div>
<PaperInput @value={{ name }}
@placeholder="Enter a Name"
@onChange={{this.changeName index}}/>
</div>
{{/each}}
</div>
// component.js
changeName(index, nameToBeUpdated) {
// change the name here...
}
Upvotes: 4