Xameer
Xameer

Reputation: 31237

How to use a promised function in a react app

I'm trying to implement Bullet train API in a React web app. According to their node client documentation, I have setup the following function:

export const isFeatureEnabled = async (nameOfTheFeature) => {
    return new Promise((resolve) => {

        bulletTrain.init({
            environmentID: BULLET_TRAIN_ENV_ID
        });

        bulletTrain.hasFeature(nameOfTheFeature)
            .then((featureFlag) => {
                if (featureFlag[nameOfTheFeature].enabled) {
                    resolve(true);
                }
            })
            .catch(err => resolve(false));
    });
}

This is called in regular components like this:

render() {
  return (<div>{await isFeatureEnabled('feature1') && <p>feature1 is enabled</p>}</div>)
};

which throws this:

Parsing error: Can not use keyword 'await' outside an async function

If we add the async keyword, with a proper return statement:

async render() {
  return (<div>{await isFeatureEnabled('feature1') && <p>feature1 is enabled</p>}</div>)
};

Then it throws:

Your render method should have return statement

So what is the correct way to use this promised function inside a react app?

Upvotes: 1

Views: 94

Answers (3)

Rico
Rico

Reputation: 348

You can't use promise at there, the proper way:

import React, { useEffect, useState } from 'react'
import bulletTrain from '../somewhere'
import BULLET_TRAIN_ENV_ID from '../somewhere'

export default function featureComponent({ featureName }) {
  const [featureEnabled, setFeatureEnabled] = useState(false)

  useEffect(() => {
    bulletTrain.init({
      environmentID: BULLET_TRAIN_ENV_ID
    })

    bulletTrain
      .hasFeature(featureName)
      .then(featureFlag => {
        if (featureFlag[featureName].enabled) {
          setFeatureEnabled(true)
        }
      })
      .catch(err => setFeatureEnabled(false))
  }, [featureName])

  return <div>{featureEnabled && <p>{featureName} is enabled</p>}</div>
}

Append isFeatureEnabled function re-use answer below:

import React, { useEffect, useState } from 'react'
import isFeatureEnabled from '../somewhere'

export default function featureComponent({ featureName }) {
  const [featureEnabled, setFeatureEnabled] = useState(false)

  useEffect(() => {
    const checkAndSetEnabled = async () => {
      const enabled = await isFeatureEnabled(featureName)
      setFeatureEnabled(enabled)
    }
    checkAndSetEnabled()
  }, [featureName])

  return <div>{featureEnabled && <p>{featureName} is enabled</p>}</div>
}

Upvotes: 1

Jai
Jai

Reputation: 74738

I would suggest you not to use await keyword in render instead use componentDidMount and constructor for this and use state object to check:

constructor(props){
    super(props);
    this.state = { isFeatEnabled: false };
}

componentDidMount(){
    this.setState({isFeatEnabled:isFeatureEnabled('feature1')})
}

Now in the render:

render() {
  return (<div>{this.state.isFeatEnabled && <p>feature1 is enabled</p>}</div>)
};

And remove the async from the method.

Upvotes: 1

Biswa Soren
Biswa Soren

Reputation: 325

call function isFeatureEnabled inside an async function during mount (before/after your wish)

example -


export const isFeatureEnabled = async (nameOfTheFeature) => {
    return new Promise((resolve) => {

        bulletTrain.init({
            environmentID: BULLET_TRAIN_ENV_ID
        });

        bulletTrain.hasFeature(nameOfTheFeature)
            .then((featureFlag) => {
                if (featureFlag[nameOfTheFeature].enabled) {
                    resolve(true);
                }
            })
            .catch(err => resolve(false));
    });
}
...
componentDidMount() {
  this.checEnabled();
}
...
const checkEnabled = async () => {

const flag = await isFeatureEnabled('feature1');

this.setState({f1enabled: flag});

}
...
render() {
  return (<div>{this.state.f1enabled ? <p>feature1 is enabled</p> : null}</div>)
}

If isFeatureEnabled is in the same file keep it outside class component or else keep it in another file and export the function.

Upvotes: 1

Related Questions