I’m experiencing some unexpected behaviour when trying to implement DDAU when setting properties that are not contained in objects.
I’ve created an Ember Twiddle showing the behaviour here. The code is below:
controllers/application.js
The controller is the owner of the data, which is comprised of foo
(An object) and baz
, a string. An action called setProperty
is included, to be called when those data properties need to be updated. My understanding of DDAU is that this is done because data should only be mutated at the level which owns it.
export default Ember.Controller.extend({
init() {
this._super(...arguments);
this.foo = {
bar: 'one'
};
this.baz = 'two'
},
actions: {
setProperty(prop, value) {
this.set(prop, value);
}
}
});
templates/application.hbs
Simply inserts a component, passing in the data props and the closure action.
{{my-component
foo=foo
baz=baz
setProperty=(action "setProperty")
}}
components/my-component.js
export default Component.extend({
actions: {
updateProps() {
this.setProperty('foo.bar', 'one-updated');
console.log(this.get('foo.bar')); // one-updated
this.setProperty('baz', 'two-updated');
console.log(this.get('baz')); // two
setTimeout(() => {
console.log(`setTimeout: ${this.get('baz')}`); // two-updated
});
}
}
});
templates/components/my-component.hbs
baz value: {{baz}}<br>
foo.bar value: {{foo.bar}}<br>
<button {{action "updateProps"}}>Update Props</button>
When the Update Props
button in the component is clicked, the setProperty
action is fired and the properties are updated as defined in the action. Both foo.bar
and baz
updated in the component template as expected.
Here is where things get weird.
Immediately after each time that I call the setProperty
action from the component, I log the relevant property to the console. In the case of foo.bar
, the console shows the updated value as expected.
However, logging baz
to the console after calling setProperty
logs the initial value, not the updated one. Even weirder is that if I wrap the console.log
statement in a setTimeout
, it logs the updated value, even if no time interval is passed as an argument.
I have three questions.
- Why has
baz
not been updated by the time it is logged to the console and is there a way around this? - Why would the setTimeout make a difference?
- Am I misunderstanding the best way to implement DDAU? Do I need to fundamentally reconsider my design pattern?