Toivo Säwén
Toivo Säwén

Reputation: 2042

Use object parameters as arguments for function

I am sure this has been answered before, but searching only yields results for passing an actual object as a function arguments, however I would like to destructure an object and use its parameters as input arguments for a function.

I am importing the function foo() from an external library and would like to supply its arguments using an object containing them. Here is foo.js (note that my use case has a lot more input arguments):

export function foo(arg1, arg2) {
  doStuff()
}

Here is my code; the following works :

import { foo } from 'foo'

const args = {
  arg1: "value1",
  arg2: "value2",
}

const { arg1, arg2 } = args
foo(arg1, arg2)

I would like to be a bit more concise and avoid repeating the variable names arg1 and arg2, along the lines of:

import { foo } from 'foo'

const args = {
  arg1: "value1",
  arg2: "value2",
}

foo(args) // doesn't work, apparently I have to do something more to the args object here

But this code doesn't work (arg1 gets the value of args and arg2 is undefined), I assume that this can be achieved, e.g. using the spread operator somehow, but how?

Upvotes: 1

Views: 98

Answers (3)

Alek Angelov
Alek Angelov

Reputation: 111

destructure the object in the function declaration like so:

function({arg1 = "", arg2 = 0}) {doStuff()}

and remember to always add default values :)

EDIT: what you're doing is impossible basically, because you can't use iterators like this foo(..{arg1, arg2). A solution to this would be unwrapping the object values using Object.values converting them into an array and then destructuring that.

function foo(arg1, arg2) {
  console.log(arg1, arg2);
}

function unwrap(object) {
  return Object.values(object);
}

foo(...unwrap({ x: "1", y: "2" }));

at this point tho you'd be better off using an array like so:

foo(...[1, 2]);

Upvotes: 3

user11067476
user11067476

Reputation:

Use Map instead object to save insertion order:

const args = new Map();

args.set('arg1', 'value1');
args.set('arg2', 'value2');

foo(...args.values());

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386570

You could take a function for unwrapping the arguments object and spread the result for calling the wanted function without changing the function's signature.

// given function
function foo(arg1, arg2) {
    console.log(arg1, arg2);
}

const
    unwrap = ({ arg1, arg2 }) => [arg1, arg2], // get all properties in wanted order
    args = { arg1: "value1", arg2: "value2" };

foo(...unwrap(args));

Upvotes: 0

Related Questions