0
\$\begingroup\$

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.

  1. 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.

  1. 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 
      },
    ],
  },
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.