I have the following function where data may not exist during the many nested steps
to obtain data. To prevent errors, doing the checks as follows.
- Is there a more elegant way to do this?
Please note that Optional chaining is not an option due to the project structure
and difficulties in upgrades at this stage.
Something like this would have been cleaner but as said Optional chaining is not an option.
let Component = configMap[environment][locale]
?.find(config => config['names']?.includes(id))?.config;
The logic is to search through the config map and select the Component if it exists within the dev
key. Else use the Component within the default
key.
Example of this configMap is mentioned below. Actual map is much larger and has more keys than just dev
.
- Also looking for feedback if I could write these
ifs
in a more cleaner way.
Appreciate any feedbacks. Thanks.
To note, this is a React project.
import { configMap } from '../maps';
const get = (locale, environment, id) => {
if (!id) return <Fragment />; // id example: '1', '12', '34'
let Component = configMap[environment][locale]
&& configMap[environment][locale]
&& configMap[environment][locale].find(config => config['names'] && config['names'].includes(id))
&& configMap[environment][locale].find(config => config['names'].includes(id)).config;
if (!Component) {
Component = configMap['default'][locale]
&& configMap['default'][locale]
&& configMap['default'][locale].find(config => config['names'] && config['names'].includes(id))
&& configMap['default'][locale].find(config => config['names'].includes(id)).config;
}
if (Component) {
return <Component />
}
return <Fragment />;
}
Just for reference, the configMap will look like this.
export const configMap = {
'dev': {
'australia': [
{
names: ['12'],
config: AndroneDesignComponent, // AndroneDesignComponent is a React component
},
{
names: ['34'],
config: ShreadDesignComponent, // ShreadDesignComponent is a React component
},
],
},
'default': {
'australia': [
{
names: ['1'],
config: ThymeDesignComponent, // ThymeDesignComponent is a React component
},
{
names: ['12'],
config: DefaultDesignComponent, // DefaultDesignComponent is a React component
},
{
names: ['34'],
config: DefaultDesignComponent, // DefaultDesignComponent is a React component
},
],
},
}
1 Answer 1
One option could be to extract the checking and getting of the component to its own function, such as:
import { configMap } from '../maps';
const getComponentFromConfigMap = (env, locale, id) => {
const actualEnv = Object.keys(configMap).includes(env) ? env : "default";
const actualLocale = Object.keys(configMap[actualEnv]).includes(locale) ? locale : null;
if(!actualLocale) {
return null;
}
const component = configMap[env][locale].find(config => config['names'] && config['names'].includes(id)) || { config: null }; // Get the correct component config, or assign a null value to it
return component.config;
}
const get = (locale, environment, id) => {
const Component = getComponentFromConfigMap(environment, locale, id); // This will contain the correct component or null, if no matching component was found
if (Component) {
return <Component />
} else {
return <Fragment />;
}
}
One thing to also note is that checking for the id
in the if (!id) return ...
statement might give unexpected results, if the id
can be something that is falsy (e.g. if someone is trying to get
with an id of 0).
Further, in the suggestion above, on line const component = configMap[env][locale].find(config => config['names'] && config['names'].includes(id))
the config['names'] &&
might not be needed, if the object is guaranteed to always have names
(even if it's empty) as was the case in the example configMap
provided.