Souvik Ghosh
Souvik Ghosh

Reputation: 4606

React setState after Promise resolves in componentDidMount

I am still new to React and trying to wrap my head around.

I am fetching some data from an API in ProjectAPI.js file.

const getProjects = async () => {
    const projectsAPI = Common.baseApiUrl + '/project';
    let projects = [];
    axios.get(projectsAPI)
    .then((response) => {
        for (let i = 0; i < response.data.length; i ++){
            let project = {
                projectNameInitials: "NO",
                projectNumber: response.data[i].projectNumber,
                projectName: response.data[i].projectName,
                clientName: response.data[i].client,
                currentStage: response.data[i].currentStage,
                lastUpdated: response.data[i].updatedOn
            }
            projects.push(project);
        }
    })
    .catch((error) => {
        console.log(error);
    });
    return projects;
}

Then, in my React component I call this function and sets the state after the Promise resolves using then.

componentDidMount(){
    ProjectAPI.getProjects().then((response) => this.setState({projects: response}));
}

I try to retrieve the same from the state in my render() function.

render(){
    const {
        projects,
      } = this.state;
    //...
}

This does not work and I get projects as empty array inside render() function. However, using the React dev tools, I can see the state is having the exact data. Interestingly, when I modify one of the state value manually using React dev tools, the render() is able to retrieve the state data, since it triggers the render() again. Any idea what I am doing wronng here?

Upvotes: 0

Views: 203

Answers (2)

Giang Le
Giang Le

Reputation: 7044

Cause getProjects return empty array. Try this

const getProjects = () => {
    const projectsAPI = Common.baseApiUrl + '/project';
    let projects = [];
    return axios.get(projectsAPI)
    .then((response) => {
        for (let i = 0; i < response.data.length; i ++){
            let project = {
                projectNameInitials: "NO",
                projectNumber: response.data[i].projectNumber,
                projectName: response.data[i].projectName,
                clientName: response.data[i].client,
                currentStage: response.data[i].currentStage,
                lastUpdated: response.data[i].updatedOn
            }
            projects.push(project);
        }
        return projects
    })
    .catch((error) => {
        console.log(error);
    });
}

Upvotes: 3

niks
niks

Reputation: 466

You just need to wait for data to come, because in this case render method getting called before your data comes from api.

So Just put condition before you render if state is null then render null else your html

render(){
const {
    projects,
  } = this.state;
{projects && 'your code' }

}

Upvotes: 0

Related Questions