0

Here's the code in question:

Object.entries({
    orderStatus: null,
    orderType: null,
    limit: 25,
    offset: null,
    sortFields: null
}).reduce((acc, [a, b]) => b ? acc[a] = b : acc, {});

A console.log shows that the first time acc[a] is set, it just replaces acc with the string in a, then tries assign a property to acc (which is now a string) and throws the TypeError. When I use:

.reduce((acc, [a, b]) => b ? {...acc, ...{[a]: b}} : acc, {});

it works like a dream. Why would acc[a] be setting acc to 25 once it hits limit? shouldn't that be the same as acc["limit"] = 25?

matwlev
  • 315
  • 1
  • 2
  • 6
  • Because `acc[a] = b` "returns" the content of `b` -> [12.4 Expression Statement](http://www.ecma-international.org/ecma-262/5.1/#sec-12.4) – Andreas Sep 27 '18 at 15:34
  • [javascript - Value returned by the assignment](https://stackoverflow.com/questions/16027247/value-returned-by-the-assignment) – Andreas Sep 27 '18 at 15:40

1 Answers1

0

The callback function in reduce has to return the accumulated value.

In your conditional expression, you return the object in acc when b is falsey.

But when it's truthy, you return acc[a] = b. This returns the value that was assigned, i.e. b, not the value of acc.

A better way to write this would be with an ordinary if:

.reduce((acc, [a, b]) => { 
    if (b) {
        acc[a] = b;
    }
    return acc; }, {})

You could also use a comma expression to perform the assignment and then return the object separately:

.reduce((acc, [a, b]) => b ? (acc[a] = b, acc) : acc, {});
Barmar
  • 741,623
  • 53
  • 500
  • 612