0

I'm trying to quickly pull out ‘value’ property from some objects using destructuring.. is there a simple way to get it from this? I think it might be possible with some complicated destructuring thing i haven’t quite grocked.

I know I could use loops and such, but I'd like to make it a bit more elegant. I'm looking for a non-repetitive, ideally 1-2 line solution. I wanted to use a map, but that only works on an array...

formData = {
  name: {val: 'myName', key: 'value', etc: 'more data'}
  province: {val: 'myProvince', key: 'value', etc: 'more data'}
  dateOfBirth: {val: 'myBDAY!', key: 'value', etc: 'more data'}
}


//desired outcome:
{
  name: 'myName',
  province: 'myProvince',
  dateOfBirth: 'myBDAY!'
}


//attempt 1
let customer = { name, province, dateOfBirth} = formData; //hrm doesn't get me there
Damon
  • 10,493
  • 16
  • 86
  • 144
  • Where are you specifying that it should use the `val` property of each element when destructuring? – Barmar Nov 26 '15 at 01:47
  • If you're using underscore or lodash then `pluck` it. Alternatively `Object.keys(formData).reduce(function(acc, key) { acc[key] = formData[key].val; return acc; }, {});` – Jared Smith Nov 26 '15 at 01:50
  • @Barmar nowhere.. it was a bad 'try', but I couldn't think of how to do it nicely. – Damon Nov 26 '15 at 01:51
  • @JaredSmith Hmm! don't want to include lodash for one thing.. I'm trying to ES6 it – Damon Nov 26 '15 at 01:52

4 Answers4

2

Destructuring is used to assign multiple variables from different elements of an array or object, that's not what you're doing. You can just do:

let customer = { 
    name: formData.name.val, 
    province: formData.province.val,
    dateOfBirth: formData.dateOfBirth.val
}

If you don't want to list all the properties explicitly, just use a loop.

let customer = {};
for (var k of Object.keys(formData)) {
    customer[k] = formData[k].val;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • That works alright, but there's an unwanted (at least by me) level of repetition (the actual code has 8 properties and is an extra level deep) – Damon Nov 26 '15 at 01:53
  • Then you may just want to do the `for-in` loop. – Barmar Nov 26 '15 at 01:53
  • 1
    Since this is ES6, it'd be much safer to do `for (var k of Object.keys(formData)){` to avoid picking up enumerable props in the prototype chain. – loganfsmyth Nov 26 '15 at 02:03
  • I'm still not fluent in all the new ES6 features. – Barmar Nov 26 '15 at 02:05
1

A hard to read one-liner would be:

let customer = Object.keys(formData).reduce(
        (acc, key) => Object.assign(acc, {[key]: formData[key].val}), {});

to grab .val off every value in the object, and return a new object with the same keys.

That's basically the equivalent of:

let customers = {};
for (const key of Object.keys(formData)) customers[key] = formData[key].val;
loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
1

Since you didn't like Barmar's answer, you can use a combination of Object.keys and the resulting array's reduce method:

let customer = Object.keys(formData).reduce(function(acc, key) {
    acc[key] = formData[key].val;
    return acc;
}, {});
Jared Smith
  • 19,721
  • 5
  • 45
  • 83
1

You said you wanted to use destructuring… so let's do that:

let customer = {};
for (let k in formData) ({[k]: {val: customer[k]}} = formData);

But really, avoid that, and use clear and readable property assignment instead :-)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375