34

I am setting lots of properties with a series of set calls e.g.

this.set('prop1', value1);
this.set('prop2', value2);
.......

Is there a way to do this in one call (similar to when I create an object)? E.g.

this.setMultiple({prop1: value1, prop2: value2});

I still don't fully grok Ember's inheritance model. Maybe something along the lines of reopen?

Abdull
  • 26,371
  • 26
  • 130
  • 172
ghempton
  • 7,777
  • 7
  • 48
  • 53
  • Hm, if I were writing this API, I'd make `set` polymorphic, and accept either a key and a value, or an object consisting of key-value pairs. Don't see anything in the documentation about this, though. – Matt Ball Jan 06 '12 at 03:00
  • 1
    Dear Google, please index this: "mass assignment Ember.js" – Jo Liss Jun 20 '12 at 15:31

2 Answers2

58

There is actually a function for this: setProperties. You can use it like this:

obj.setProperties({prop1: value1, prop2: value2})

obj should be instance of Ember.Object.

oruen
  • 728
  • 6
  • 7
  • This works great, but the side-effect issue that I'm having is that I have an observable that observes three properties, and even if I only do one mass call like this, it fires off three times if all of the properties are called. – johncho Sep 07 '12 at 16:00
  • 1
    @JohnCho Perhaps my anwser here could help: http://stackoverflow.com/a/13317170/373254 – sly7_7 Nov 14 '12 at 16:37
  • Amazing. I'm going to have to try this out. It's almost a good thing that my project got put on hold. – johncho Nov 16 '12 at 20:24
  • I was looking for it for some time... Thanks for clean explanation. It did the charm for me. – Adrian Grzywaczewski Jan 07 '17 at 00:33
  • @ouren is the something like Ember.setProperties(obj, {prop:value}) ? so that it will work on all objects and not only ember objects ? – amitava mozumder Jul 25 '19 at 08:13
29

As @oruen points out in his correct answer, you are describing setProperties(...).

One potential issue to be aware of is that according to the JS spec the order of properties on an object is indeterminate. (See Elements order in a "for (… in …)" loop).

If you don't care about order, or are confident that the JS implementations you are targeting will respect your order, setProperties should work for you.

When setting multiple properties, you should consider using Ember.beginPropertyChanges() and Ember.endPropertyChanges(). The former suspends the observer triggers and the latter restores it and flushes. This approach can improve performance. setProperties does this for you.

Also notable is Ember.changeProperties, which accepts a callback and calls Ember.beginPropertyChanges, then your callback, and then Ember.endPropertyChanges, even if your callback raised an exception. Example usage:

Ember.changeProperties(function() {
  obj1.set('foo', mayBlowUpWhenSet);
  obj2.set('bar', baz);
});

Hope that helps!

Community
  • 1
  • 1
Luke Melia
  • 8,389
  • 33
  • 41
  • Beautiful. I needed to do a rollback, but it kept triggering some methods that were observing the properties before all of the properties could be reset. Thus causing havoc in my code. This Ember.changeProperties was the key to getting everything set to null that I needed and also doing a model.rollback(). – bfcoder Dec 17 '13 at 06:18