2

This is probably something that Ruby does better, but is there a better way to write this Javascript code (for React):

handleCellChange: function(rowIdx, prop, val) {
    var updateObj = {};
    updateObj.data = {};
    updateObj.data[rowIdx] = {};
    updateObj.data[rowIdx][prop] = { $set: val };

    var newState = React.addons.update(this.state, updateObj);
justingordon
  • 12,553
  • 12
  • 72
  • 116

2 Answers2

7

In ES6 you can use computed property names:

updateObj = { data: { [rowIdx]: { [prop]: {$set: val} } } };

You can use this in Traceur or Firefox nightly, etc. (but not yet in node --harmony).

Here is a thing which will transpile this syntax for you: https://www.npmjs.org/package/es6-computed-property-keys.

For more information see http://wiki.ecmascript.org/doku.php?id=harmony:object_literals#object_literal_computed_property_keys. Also see "computed properties" item in http://kangax.github.io/compat-table/es6/#.

  • I still wish they'd gone with the fat arrow for this, instead of using it for arrow functions. That way the syntax would have not only been in line with Perl, Ruby, Erlang maps, and Julia, but even lined up nicely with Ruby 1.9+'s literal Symbol syntax: `{ foo: 1 }` vs `{ foo => 1 }` would mean basically the same thing (except for string vs symbol) in both languages. Ah, well. – Mark Reed Aug 26 '14 at 04:34
  • Don't know the background for that decision, but I suppose there is some rationale for preserving the semantics of the colon, or avoiding a situation where what follows the property name (`:` vs. `=>`) changes its meaning from literal to expression. –  Aug 26 '14 at 04:56
  • Thanks. Interesting use of brackets (for my rubyist eyes). – justingordon Aug 26 '14 at 05:28
1

Javascript's object literal notation (pre-ES6) has no provision for variable keys. You could reduce the number of assignments a bit, though:

handleCellChange: function(rowIdx, prop, val) {
  var updateObj = { data: {} };
  (updateObj.data[rowIdx] = {})[prop] = { $set: val };

You may or may not consider that any improvement - more concise, but probably less readable. I would wholeheartedly recommend that you add the nested data object to the initial assignment to updateObj (which should be declared with var, btw) as I did above. However, using the result of the initialization of data[rowIdx] as a value that you then index on the same line is of rather more questionable value.

Mark Reed
  • 91,912
  • 16
  • 138
  • 175