0

I created a function that should return an object with user data. I want the function to accept an object as a parameter and I'd like this object to be defined inside the function with all the values pre-defined as default parameters in case they are not passed at a function call. The example code has only 2 values but I will need to pass over 15. How can I achieve such a solution?

const userCreator = (name, age) => {
  if (name === undefined) {
    name = 'John'
  }
  if (age === undefined) {
    age = 25
  }
  return {
    name:name,
    age:age
  }
};
uma
  • 13
  • 2
  • Welcome to Stack Overflow! Please take the [tour] (you get a badge!) and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) Your best bet here is to do your research, [search](/help/searching) for related topics on SO and elsewhere, and give it a go. ***If*** you get stuck and can't get unstuck after doing more research and searching, post a [mcve] showing your attempt and say specifically where you're stuck. People will be glad to help. – T.J. Crowder Nov 26 '21 at 07:27
  • Side note: You can apply those defaults directly in the parameter list: `const userCreator = (name = "John", age = 25) => { /*...*/ };` – T.J. Crowder Nov 26 '21 at 07:29
  • Does this answer your question? [ES6 Object Destructuring Default Parameters](https://stackoverflow.com/questions/26578167/es6-object-destructuring-default-parameters) – jonrsharpe Nov 26 '21 at 07:29

2 Answers2

1

...and I'd like this object to be defined inside the function with all the values pre-defined as default parameters in case they are not passed at a function call.

I think you're saying:

  • You want the function to accept an object
  • You want all the properties of that object to be optional with defaults specified by the function

To do that, you can use destructuring defaults. But see also below, because in this specific case, where you want to return an object, you may want to use a different approach.

But let's start with just basic destructuring without defaults, then add them:

const userCreator = ({ name, age }) => {
//                   ^−−−−−−−−−−−^−−−−−−−−−−−−−−−− destructuring
    // ...stuff with `name` and `age` here...
    return {
        name,
        age,
    };
};

To add defaults for those properties, you add them within the destructuring pattern (the {} where the parameter name would otherwise be):

const userCreator = ({ name = "John", age = 25, }) => {
//                         ^^^^^^^^^−−−−−^^^^^−−−− defaults for the properties
    return {
        name,
        age,
    };
};

If there are lots, probably best to break up into lines:

const userCreator = ({
    name = "John",
    age = 25,
}) => {
    return {
        name,
        age,
    };
};

That version still expects an object to be provided, though. If you want to allow userCreator() (no parameter passed at all), you need to add a default parameter value for the object parameter:

const userCreator = ({
    name = "John",
    age = 25,
} = {}) => {
//^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−− default for the parameter
    return {
        name,
        age,
    };
};

That uses {} as the default value if no parameter is provided at all, "John" as the default if name isn't provided, and 25 as the default if age isn't provided. And since there is no name or age on the default {}, they get defaulted when you do userCreator().


The alternative approach:

Since you want to return an object, you might just accept the object parameter directly, then use property spread or Object.assign to fill in defaults, like this:

const userDefaults = {
    name: "John",
    age: 25,
};
const userCreator = (template) => {
    const result = {        // The result object we'll return
        ...userDefaults,    // Fill in defaults
        ...template         // Overwrite with any properties from the caller
    };
    // Or with `Object.assign` in older environments without property spread:
    //const result = Object.assign(
    //    {},                 // The result object we'll return
    //    userDefaults,       // Fill in defaults
    //    template            // Overwrite with any properties from the caller
    //);
    return result;
};

Property spread and Object.assign both ignore null or undefined, so if no object is passed at all, template is undefined, and

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Magic! Thank you so much! I believe the option with property spread is what I was looking for all along! Thanks again for all the detailed explanations :) – uma Nov 26 '21 at 08:44
-1

You should define default values directly in the function parameters:

const userCreator = (name = 'John', age = 25) => {
  return {
    name: name,
    age: age
  }
};
SteeveDroz
  • 6,006
  • 6
  • 33
  • 65