1

I want to create a dynamic function that returns me a variable from a string. I am using template string from ES6 but I don't know how to call this later. I need to pass a variable that keeps an object as a reference.

const checkDeviceWidth = type => {
    if (documentWidth > 1200) return `${type}Options`;
    if (documentWidth > 414) return `${type}MediumOptions`;
    return `${type}MobileOptions`;
  };

...

<Lottie
  ref={backgroundImg}
  isClickToPauseDisabled={true}
  speed={1}
  options={checkDeviceWidth('background')}></Lottie>

Returning object depending on the argument

const backgroundOptions = {
    loop: true,
    autoplay: true,
    animationData: background.default,
  };
  const backgroundMediumOptions = {
    loop: true,
    autoplay: true,
    animationData: backgroundMedium.default,
  };

With this, I am getting an error that in options I must pass an object instead of a string. How to call this later without eval() function? I am working with React

2
  • I recommend doing a switch case rather than trying to evaluate a string to a variable name Commented Nov 4, 2019 at 10:10
  • 1
    I'd recommend putting all device(width) options in an object instead of variables. Like as answered by Safi Commented Nov 4, 2019 at 10:17

4 Answers 4

5

You can put your constants to object

 const myObject = {
  backgroundOptions: {
    loop: true,
    autoplay: true,
    animationData: background.default
  },
  backgroundMediumOptions: {
    loop: true,
    autoplay: true,
    animationData: backgroundMedium.default
  }
};

then get the right property

  const checkDeviceWidth = type => {
    if (documentWidth > 1200) return myObject[`${type}Options`];
    if (documentWidth > 414) return myObject[`${type}MediumOptions`];
    return myObject[`${type}MobileOptions`];
  };
Sign up to request clarification or add additional context in comments.

1 Comment

My early morning brain didn't think of this, nice answer :p
0

Instead of keeping these objects as loner variables, move them into an object (options) and use that to pass your prop.

const options = {
  backgroundOptions: {
    loop: true,
    autoplay: true,
    animationData: background.default,
  },
  backgroundMediumOptions: {
    loop: true,
    autoplay: true,
    animationData: backgroundMedium.default,
  }
};

and use it to pass them to props:

<Lottie
  ref={backgroundImg}
  isClickToPauseDisabled={true}
  speed={1}
  options={options[checkDeviceWidth('background')]}
/>

Alternatively, you could just return your required object from the checkDeviceWidth function instead of returning a string.

Comments

0

Using eval is evil (really). If you think you really need eval, you're wrong and need to rethink a bit. This is a different approach (without using type arg in the function, which can be addressed with another HASH level):

const backgroundOptions = {
  big: {
    loop: true,
    autoplay: true,
    animationData: background.default,
  },
  medium: {
    loop: true,
    autoplay: true,
    animationData: backgroundMedium.default,
  }
};
const checkDeviceWidth = () => {
    if (documentWidth > 1200) return 'big';
    if (documentWidth > 414) return 'medium';
    return 'mobile';
  };

...

<Lottie
  ref={backgroundImg}
  isClickToPauseDisabled={true}
  speed={1}
  options={ backgroundOptions[ checkDeviceWidth() ] }></Lottie>

Comments

0

why not:

const options = {
  background: {
    default: {...},
    medium: {...},
    mobile: {...}
  },
  text: {
    default: {...},
    medium: {...},
    mobile: {...}    
  },
  size: {
    default: {...},
    medium: {...},
    mobile: {...}
  }
};

and then

const getSize = () => {
  if (documentWidth > 1200) {
    return 'default';
  } else if(documentWidth > 414) {
    return 'medium';
  } else if(....) {
    return 'some_other_size';
  }
}
}

const getOptions = checkDeviceWidth = type => {
  return options[type][getSize];
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.