Freestyle09
Freestyle09

Reputation: 5508

How to build variable from string in js?

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

Upvotes: 1

Views: 106

Answers (4)

Meir
Meir

Reputation: 14375

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];
}

Upvotes: 0

emi
emi

Reputation: 3070

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>

Upvotes: 0

Sajal Preet Singh
Sajal Preet Singh

Reputation: 379

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.

Upvotes: 0

Safi Nettah
Safi Nettah

Reputation: 1170

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`];
  };

Upvotes: 5

Related Questions