Issue
This is my function that generates and returns an array (Please see the comments in the code below):
const getStylesArray = (noteBlockSettings, blockId, key, value) => {
// ---------------------------------------------------
// noteBlockSettings parameter will be passed to this function no matter what.
// So it is definetely not undefined.
// NoteBlockSettings has bgOpacity, bgColor, primaryColor, secondaryColor, textColor keys and values.
// key and value parameters of this function are optional, so they may be undefined or not.
// ***** What i am trying to achieve is : *****
// If key parameter is passed (can be bgOpacity, bgColor, primaryColor, secondaryColor, textColor)
// use this passed parameter rather than the value in noteBlockSettings object.
// If key parameter is undefined, use the value in noteBlockSettings object.
// ---------------------------------------------------
let { bgColor, primaryColor, secondaryColor, bgOpacity, textColor } = noteBlockSettings
if (key === 'bgColor') {
bgColor = value
}
if (key === 'primaryColor') {
primaryColor = value
}
if (key === 'secondaryColor') {
secondaryColor = value
}
if (key === 'bgOpacity') {
bgOpacity = value
}
if (key === 'textColor') {
textColor = value
}
const stylesArray = [
// Here i am using the variables defined above to dynamically generate the array
// Like bgOpacity, bgColor, primaryColor, secondaryColor, textColor etc..
{
styleClass: '.head',
styleValue: `background:${addAlpha(colord(bgColor).lighten(0.075).toHex(), bgOpacity)}; border-color:${addAlpha(colord(bgColor).darken(0.06).toHex(), bgOpacity)};`,
styleTriggers: 'bgColor bgOpacity',
},
{
styleClass: '.head .options .btn-icon',
styleValue: `color:${addAlpha(colord(textColor), 0.4)};`,
styleTriggers: 'textColor',
},
{
styleClass: '.head .options .btn-icon:hover',
styleValue: `color:${primaryColor};`,
styleTriggers: 'primaryColor',
},
.
.
.
]
// Finally returning the generated array
return stylesArray
}
This is working and it is just a primitive attempt. However I don’t know how, but I feel like there should be much "smarter" way of handling this.
So, my question is: What is the best and minimal way of achieving the same result?
Solution
You can build a "final" settings object before destructuring it. Then you don’t need to check every variable:
// If `key` is passed and a valid key in the object, copy the object and overwrite
// the property.
const finalSettings = key in noteBlockSettings ?
{...noteBlockSettings, [key]: value} :
noteBockSettings;
const { bgColor, primaryColor, secondaryColor, bgOpacity, textColor } = finalSettings;
// ...
{...noteBlockSettings, [key]: value}
basically copies noteBlockSettings
and sets the property whose name is in key
to value
.
Having said that, I’m wondering why the call site simply doesn’t pass the complete settings object. That would make the API clearer.
Answered By – Felix Kling
Answer Checked By – David Goodson (BugsFixing Volunteer)