SRIKANTH D
SRIKANTH D

Reputation: 39

How to make react to wait until api data is retrieved

I am retrieving the data from an API (using axios) every 15mins and is showing in a table. However, the UI is not waiting until the api data is fetched. What mistake am I doing? Please find the below code.

const INTERVAL_DURATION = 15 * 1000 * 60;


class ApplicationDashboard extends Component {


    state = {
        defaultEnv: 'DIT',
        appsToShow: [],
        appsDataApi: [],
        env: 'DIT',
        selectedEnvs: 'DIT'
    };

    // on change of environment
    handleEnvClick = (selectedButton) => {
        this.setState({
            selectedEnvs: selectedButton
        }, () => {
            this.getAppDataByEnv(this.state.selectedEnvs);
        });
    }

    getAppDataByEnv = (selectedEnv) => {
        console.log("selected env " + selectedEnv);

        this.setState({
            defaultEnv: selectedEnv
        }, () => {
            this.setState({
                appsToShow: this.state.appsDataApi.filter(app => app.env === selectedEnv)
            });
        });
    }

    componentDidMount() {
        this._fetchAppsByIntervals = setInterval(this.getAppHealthDataFromES(), INTERVAL_DURATION);
        this.getAppDataByEnv(this.state.defaultEnv);
    }

    componentWillUnmount() {
        // clearInterval(this._fetchAppsByInterval);
        clearInterval(this._fetchAppsByIntervals);

    }

    getAppHealthDataFromES = async () => {

        const BASE_URL = 'http://localhost:8080';
        const url = `${BASE_URL}/log/v1/appinfo`;
        await axios.get(url).then(response => response.data)
            .then((data) => {
                this.setState({
                    appsDataApi: data
                })
                console.log(this.state.appsDataApi)
            });
    }

    render() {
            return ( <
                    div className = "app-dashboard-main-div" >
                    <
                    div className = "app-dashboard-container" >
                    <
                    div className = "app-dashboard-table-env-main" >
                    <
                    div className = "app-dashboard-label" >
                    Applications <
                    /div>

                    <
                    div className = "EnvGroupButtonsMain" >
                    <
                    button onClick = {
                        () => this.handleEnvClick("DIT")
                    }
                    className = {
                        `${this.state.selectedEnvs==='DIT'?'activeEnv':'inActiveEnv'}`
                    } > DIT < /button> <
                    button onClick = {
                        () => this.handleEnvClick("FIT")
                    }
                    className = {
                        `${this.state.selectedEnvs==='FIT'?'activeEnv':'inActiveEnv'}`
                    } > FIT < /button> <
                    button onClick = {
                        () => this.handleEnvClick("IAT")
                    }
                    className = {
                        `${this.state.selectedEnvs==='IAT'?'activeEnv':'inActiveEnv'}`
                    } > IAT < /button> <
                    button onClick = {
                        () => this.handleEnvClick("PROD")
                    }
                    className = {
                        `${this.state.selectedEnvs==='PROD'?'activeEnv':'inActiveEnv'}`
                    } > PROD < /button> <
                    /div>

                    ...

Could someone please help if there is some mistake in the way am invoking using axios async. Thanks in advance!

Upvotes: 1

Views: 9460

Answers (1)

Tamas Szoke
Tamas Szoke

Reputation: 5542

You don't need to call .then if you are using async/await, try:

const response = await axios.get(url);

this.setState({ appsDataApi: response.data }, () => {
  console.log(this.state.appsDataApi)
});

You can also refactor the request line like:

const { data } = await axios.get(url);

And use it as appsDataApi: data.

Update

If you want to hide the content until the request arrives, you can do something similar:

render() {
  return (
    {
      this.state.appsDataApi ?
        // insert your content here
      :
        // add a loader or an empty div here
    }
  )
}

Define the appsDataApi as null in the default state.

Upvotes: 3

Related Questions