0

I've been playing with functional javascript a bit and had an idea for a util function using deconstructing.

Is it possible using ...rest to pass the names of object keys to later filter out properties?

reading through the ...rest docs I haven't seen any mention of deconstructing.

If not what solution could solve this issue?

const stripObject = attr => ({ ...attr }) => ({ ...attr });

const getUserProps = stripObject(['_id', 'firstName']);

console.log(getUserProps({ _id: 1, firstName: 'foo', lastName: 'bar' }));

/*
I understand right now whats happening is the []
passed is being ignored and its just returning a 
function that passing in all the props 
{
  _id: 1,
  firstName: 'foo'
}
*/
Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072
Joe Warner
  • 2,928
  • 1
  • 12
  • 29

3 Answers3

2

Just in case you like to spread stuff you could spread a specially prepared Proxy :)

const stripObject = attrs => obj => ({ ...new Proxy(obj, {
    ownKeys() {
      return attrs
    }
  })
});

const getUserProps = stripObject(['_id', 'firstName']);

console.log(getUserProps({
  _id: 1,
  firstName: 'foo',
  lastName: 'bar'
}));
Yury Tarabanko
  • 39,619
  • 8
  • 73
  • 90
1

{ ...attr } in parameter position means "get all properties of the passed in object and assign it to a new object assigned to attr". I.e. you are just creating a shallow clone of the object that is passed in.

I.e. these two functions are equivalent except for the cloning part

({...foo}) => foo
foo => foo

So no, what you want is not possible (this way). You cannot declare parameters dynamically.

If you want to pull out specific props, you can do adapt this approach (One-liner to take some properties from object in ES 6) to your requirements:

const stripObject = attr => obj => pick(obj, ...attr);
Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072
  • 1
    I mean, technically you can define parameters dynamically by using the `Function` constructor, e.g. `var func = new Function(params.join(','), '...')` but you should not do that ;) – Felix Kling Jun 15 '18 at 19:19
1

After learning what I originally isn't possible solution I ended up using was to reduce over the keys initially passed then grab the prop form the object.

const stripObject = keys => obj => {
  return keys.reduce((p, c) => (
    { ...p, [c]: obj[c] }
  ), {});
};
const getUserProps = stripObject(['_id', 'firstName']);

console.log(getUserProps({
  _id: 1,
  firstName: 'foo',
  lastName: 'bar'
}));
Joe Warner
  • 2,928
  • 1
  • 12
  • 29