Ember.set and Ember.setProperties gives different results

1.6k Views Asked by At

I ran into a problem in my Ember application where setting multiple properties using Ember.set and Ember.setProperties produced a buggy result in the latter. Constructed an exact scenario here.

HBS:

Name: {{name}}<br>
Place: {{place}}<br><br>

<button {{action "modifyTogether"}}>this.setProperties({name:"Vignesh Raja",place:"Namakkal"})</button>

<br><br><br>

<button {{action "modifySeperately"}}>this.set("name","Vignesh Raja");<br>this.set("place","Namakkal");</button>

<br><br><br>

When set seperately, we get the latest value - {name:"Vignesh Raja", place:"Namakkal"}<br>
When set together, we get the latest value from the observer- {name:"Vignesh Raja", place:"Chennai"}<br>
<br>
<br>

JS:

import Ember from 'ember';

export default Ember.Controller.extend({
    name:"Vignesh",
    place:"Nmkl",

    handleName1 : function(){
        this.set("place","Chennai");
    }.observes("name"),

    actions:{
        modifyTogether:function(){
            this.setProperties({name:"Vignesh Raja",place:"Namakkal"})
        },

        modifySeperately:function(){
            this.set("name","Vignesh Raja");
            this.set("place","Namakkal");
        }
    }
});

Ember Twiddle

In the above code, clicking first button (Ember.setProperties) gives Name: Vignesh Raja Place: Chennai, but clicking second (multiple Ember.set) gives Name: Vignesh Raja Place: Namakkal

1

There are 1 best solutions below

0
On

The problem I ran into was due to the Ember Observer assigned to the name property.

While updating separately, first this.set("name","Vignesh Raja") sets the value of name property. Then its observer is fired and place property gets changed to Chennai. After these, second statement, this.set("place","Namakkal") is fired. So we get Namakkal as the final value.

Hence the result - Name: Vignesh Raja Place: Namakkal

While updating together, Ember.setProperties buffers the observers until all the properties passed are updated. It groups the property changes using Ember.beginPropertyChanges, and the value changed notifications are not sent to the observers. Once the properties are set, Ember.endPropertyChanges is called which in turn sends the notifications to the observers. So in the above example, this.setProperties({name:"Vignesh Raja",place:"Namakkal"}), sets the properties name and place and after finishing, the observer changes the property place to Chennai.

Hence the result - Name: Vignesh Raja Place: Chennai.

So if using the Ember.setProperties, Make sure any observer of any properties you set, won't change the value of other properties.