40

Is it possible to destructure an object while returning it at the same time. For example, to change this code:

const mapStateToProps = ({ newItem }) =>{
  const { id, name, price } = newItem;
  return { id, name, price };
}

To something like this:

const mapStateToProps = ({ newItem }) =>{
  return { id, name, price } = newItem;
}
kfcobrien
  • 481
  • 1
  • 5
  • 11
  • 7
    Thanks for your helpful reply Pointy, and yes of course I have tried it but with so much syntactic sugar in ES6, I thought there may be a correct way of doing it – kfcobrien Jan 22 '17 at 17:42
  • 1
    Your code works already, not sure what "correct way of doing it" you want. – Oriol Jan 22 '17 at 17:44
  • @kfcobrien well if you tried it, what happened? That sort of information helps people understand more about your question and the specifics of what you're attempting to do. – Pointy Jan 22 '17 at 17:47
  • 1
    it returns an "id is not defined" error – kfcobrien Jan 22 '17 at 17:55
  • @Oriol No, it really doesn't. It does assign global variables and returns the object from the argument. – Bergi Jan 22 '17 at 17:57
  • OK, the codes are not equivalent, but the second one destructures an object and returns it, like asked in the description. – Oriol Jan 22 '17 at 18:01

4 Answers4

33

No, it's not possible.

(Disclaimer: your syntax works and does both destructuring and returning, but it is equivalent to

({ id, name, price } = newItem); // assigns global variables
return newItem;

which is probably not what you wanted)

To do what you want (which I assume is creating a new object), you need to use an object literal (potentially with shorthand property notation). See also One-liner to take some properties from object in ES 6:

const mapStateToProps = ({newItem: {id, name, price}}) => ({id, name, price});
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    thank you, this is exactly what I was looking for!! Sorry I was not clearer in my description :) – kfcobrien Jan 22 '17 at 18:04
  • 1
    Nice. So for example, I want to assign a copy of `newItem` and pick only some of the props, I can do it in one line: `const newItemCopy = (({name, price}) => ({name, price}))(newItem)` – Yahya Nov 12 '19 at 07:37
  • in case someone needs good instructions on destructuring please go here : [link](https://dmitripavlutin.com/javascript-object-destructuring/) – imshashi17 Oct 21 '20 at 14:13
3

In ES6 you can also do the following, if you want to pass all the newItem keys

const mapStateToProps = ({ newItem }) => ({ ...newItem });
mhlavacka
  • 691
  • 11
  • 25
  • 1
    This works when all properties should be returned. But when specific properties needs to be returned, the first approach suits better. – Andrey Luiz Aug 22 '18 at 13:12
  • 8
    That's exactly the same as just returning `newItem` if I'm not mistaken... – kwyntes Dec 15 '18 at 17:49
  • They're not the same, returning newItem returns a reference to the newItem property on the original object where this returns a new object with the properties that newItem had. [codepen](https://codepen.io/calebwheeler/pen/oNWddVP) – caleb wheeler Jul 30 '21 at 18:15
2

There is a way to do what you want without this repetition.

But this require the usage of forbidden js feature; and this isn't destructuring anymore.

So I would not recommend it at all.

const mapStateToProps = ({ newItem }) =>{
  with (newItem) {
   return { id, name, price };
  }
}
ludo
  • 374
  • 1
  • 9
  • The use of `with` is no longer recommended . Refer this for better understanding: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with – EternalObserver Jan 10 '23 at 06:04
0

I would recommend another approach to achieve the same result.

const mapStateToProps = ({ newItem }) =>{
  return {
    id: newItem.id,
    name: newItem.name,
    price: newItem.price
  };
}

Or shorter:

const mapStateToProps = ({ newItem: i }) =>{
  return {
    id: i.id,
    name: i.name,
    price: i.price
  };
}

Or even shorter:

const mapStateToProps = ({newItem: i}) => ({
  id: i.id, name: i.name, price: i.price
})

Here are some reasons why this would be better:

jiv-e
  • 483
  • 6
  • 8
  • Question was "is it possible" not how performant is it – kfcobrien Nov 24 '22 at 18:17
  • That is true. Reasoning: I added the performance analysis to support the fact that it's better not to use destructuring in this case. I stumbled upon your question when my goal was practically the same. I wanted to remove the duplication. After analysing my options I ended up to do the above. I added the answer to help people in similar situation and offer a best practice to practically do the same. If the question was purely theoretical I apologise. I should move the answer elsewhere. – jiv-e Dec 05 '22 at 15:52
  • @kfcobrien If you don't consider this answer valuable I can remove it. Do you think I should? – jiv-e Dec 07 '22 at 16:04