12

This works…

const { prop1:val1, prop2:val2 ) = req.query
val1 = val1.toLowerCase()

Though, I'm more inclined to do something like

const { prop1.toLowerCase():val1, prop2:val2 } = req.query

or

const { prop1:val1.toLowerCase(), prop2:val2 } = req.query

neither of which work. Is there a syntax similar to this or must manipulations be done outside of the destructing assignment?

tjfwalker
  • 494
  • 3
  • 18

2 Answers2

5

No, this is not possible. A destructuring assignment does only assign, it does not do arbitrary transformations on the value. (Setters are an exception, but they would only complicate this).

I would recommend to write

const { prop1, prop2:val2 ) = req.query;
const val1 = prop1.toLowerCase();

or, in one statement:

const { prop1, prop2:val2 ) = req.query, val1 = prop1.toLowerCase();
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Downside is there are two variables referring to different versions of the same data, which can cause confusion/bugs. I imagine that's what the OP is trying to avoid. A utility function may be better. –  Mar 03 '18 at 19:24
  • @doodlemeister, how do you imagine a util function being implemented to make it better? – tjfwalker Mar 03 '18 at 19:32
  • @TJWalker: If by better, you mean avoiding the vars, then I worked up a solution that I'll post. It's definitely more verbose though, as to make it generic, it uses callback functions for the properties that need to be transformed. –  Mar 03 '18 at 19:34
  • @doodlemeister I'm sure if that's a problem one could use a block scope or IIFE for containing the `prop1` variable, but it only will become more verbose. – Bergi Mar 03 '18 at 20:41
  • 1
    @doodlemeister `const { val1, val2 } = (({prop1, prop2}) => ({val1: prop1.toLowerCase(), val2: prop2}))(req.query);` – Bergi Mar 03 '18 at 20:42
1

The trouble with the temporary variable solutions is that they introduce different versions of the same data into the scope, which can lead to bugs.

This solution creates a utility function that receives the object to be destructured as well as a second object that is a mapping of property names to transformation functions. It's a little more verbose, but does the trick.

// Utility functions to perform specified transformations on an object
function transformProps(obj, trans) {
  return Object.assign({}, obj, ...Object.entries(trans).map(([prop, fn]) => 
    prop in obj ? {[prop]: fn(obj[prop])} : null
  ));
}

const { prop1:val1, prop2:val2 } = transformProps(
  {prop1: "FOO", prop2: "BAR"},
  {prop1: v => v.toLowerCase()} // Transformations to be made
);

console.log(val1, val2);