I have the following .hbs
<button {{action "addToObject"}}>
Add to Object
</button>
<br />
{{#each this.sortedDictionary as |item|}}
{{item.name}}<br />
{{/each}}
and the corresponding .js code for it:
import Component from '@ember/component';
import EmberObject, {set, computed, observer} from '@ember/object';
export default Component.extend(
{
myDictionary: null,
counter: 0,
init()
{
this._super( ...arguments );
console.log( "test-comp init" );
this.myDictionary = {};
set( this.myDictionary, "hello", "42" );
},
sortedDictionary: computed( 'myDictionary', function()
{
let sortedDictionary = [];
if ( this.myDictionary )
{
const keys = Object.keys( this.myDictionary );
keys.sort();
console.log( "test-comp keys", keys );
sortedDictionary = keys.reduce( ( sorted, itemName ) =>
{
const value =
{
name: itemName,
...this.myDictionary[ itemName ]
}
sorted.push( value );
return sorted;
}, []);
}
console.log( "test-comp sortedDictionary", sortedDictionary );
return sortedDictionary;
}),
actions:
{
addToObject()
{
set( this.myDictionary, `hello${this.counter}`, "42" );
this.counter++;
console.log( "test-comp addToObject", this.myDictionary );
}
}
});
In my mind, when I press the Add to Object button, my .hbs should rerender. However, it does not.
I am assuming this is because sortedDictionary is not recomputed and cannot detect that myDictionary has changed.
What is the correct solution to this problem?
In your ember computed function, only dependency is myDictionary
. So computed will fire only theres a reference change to myDictionary
object. You can tweak this by calling dictionary event change or adding another dependency which changes when firing the action (in your example, counter
). If you are using counter
as a dependency for the computed property, you have to use set
function to trigger dependency change.
In addition to that, hbs doesn't need to have this
to get myDictionary
since it uses related component as its context