5

I am trying to get the es6 syntax working for this code fragment.

let checkList = [1, 2].map(i => "Check " + i)

let checks = checkList
  // .reduce((acc, check) => Object.assign(acc, {[check]: {valid: false}}), {})
  .reduce((acc, check) => {...acc, {[check]: {valid: false}}}, {})
console.log(checks)

The output if i use the commented line in https://babeljs.io is as below and which is what i want to get using the new syntax.

Object {
  "Check 1": Object {
    "valid": false
  },
  "Check 2": Object {
    "valid": false
  }
}

I am not sure if there is a syntax error in this code. I tried selecting all the presets in babeljs but it does't compile properly.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
Akshay Patil
  • 611
  • 1
  • 10
  • 23
  • It's not ES6 syntax. You cannot use spread syntax in object literals. It's some experimental proposed syntax. – Bergi Jun 21 '17 at 18:47
  • Possible duplicate of [ECMAScript6 arrow function that returns an object](https://stackoverflow.com/questions/28770415/ecmascript6-arrow-function-that-returns-an-object) – Bergi Jun 21 '17 at 19:12
  • Keep in mind that spread in reduce [is anti-pattern](https://www.richsnapp.com/article/2019/06-09-reduce-spread-anti-pattern) – lazy.lizard Jul 29 '21 at 09:22

2 Answers2

6

Object spread is stage 4 proposal and isn't part of existing specifications. Stage 3 preset should be enabled in Babel, namely, transform-object-rest-spread.

There are syntax errors in the code above that will prevent it from being compiled properly even with required presets.

It should be

let checks = checkList
  .reduce((acc, check) => ({...acc, [check]: {valid: false}}), {});
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • 2
    While this works, it's inefficient. Using the spread operator in reduce() is O(n^2) instead of O(n). https://prateeksurana.me/blog/why-using-object-spread-with-reduce-bad-idea/ – mcv Jul 07 '22 at 08:02
  • It's true. This is the case for older Object.assign, `=> Object.assign(acc, {[check]: {valid: false}})` – Estus Flask Jul 07 '22 at 08:27
5

First of all you don't have wrap the properties in an extra object (unless you also want to use the spread operator on that).

So {...acc, {[check]: {valid: false}}} can become {...acc, [check]: {valid: false}}

This means you're adding an object to accumulator. The key of this object is the name you assigned it (Check[n]) and the values are the ones you set ({valid...}).

Secondly, as far I know, you cannot use the spread operator without explicitly a new value. So you should either write your state on a new line like:

let checks = checkList.reduce((acc, check) => {
  return {...acc, [check]: {valid: false}}
}, {})

Or wrap it in extra parentheses:

let checks = checkList.reduce((acc, check) => ({...acc, [check]: {valid: false}}) , {})
Sebass van Boxel
  • 2,514
  • 1
  • 22
  • 37