Api Data Not Being Copied and Stored into the State in React, How Would I Do This?

So I'm new to react and I have this predicament. I'm firstly using axios to get a "database" from JSONPlaceholder which I can then store in the state and then I want to call an API to fill in missing data that was not in the database. Just a quick run down of the code, I am using grabdata to grab the data that I need from JSONPlaceholder and put it in the array. Then I am using callsetcycle, which calls the setcycle method which should cycle through the array positions and get the data that I need and then store it in the array of suggesteddestinations too. My Problem is, is that the information in not called and stored and I don't understand why. Any help will be appreciated.

export class App extends Component {
state = {
    suggesteddestinations : [],
    scheduleddestinations : [],
    loaded: false
}


componentDidMount = () =>{
    this.grabData().then(
        this.callsetCycle()
    )
}

callsetCycle = () =>{
    if (this.state.suggesteddestinations.length>0){
        console.log("2")
        this.setCycle().then(
            this.setState({
                loaded: true
        }))
    }
}

grabData = () =>{
    return new Promise(() => {
        var url = "";
        Axios.get(url)
        .then(contents => this.setState({ suggesteddestinations: contents.data}))
    });
}

setCycle = () => {
    return new Promise(() => {
        var i
        if (this.state.suggesteddestinations.length > 0){
            for (i = 0; i < this.state.suggesteddestinations.length; i++) {
                console.log("5")
                this.apiCallCurrentWeather(this.state.suggesteddestinations[i].name, i)
                this.apiCallForcast(this.state.suggesteddestinations[i].name, i)
            }
        }
    });
}

apiCallCurrentWeather = async (name, pos) => {
    const apicall = await fetch(""+name+"&units=metric&APPID=5afdbd7139b98ae3f70a76b0dda2b43b")
    await apicall.json()
    .then(data =>
        this.setState(
            this.setCurrentWeatherProperties(data, pos)
        )
    )
}

setCurrentWeatherProperties = (data, pos) => {
    this.state.suggesteddestinations[pos].temp = data.main.temp.toString()
    this.state.suggesteddestinations[pos].desc = data.weather[0].main
    this.state.suggesteddestinations[pos].tempmax = data.main.temp_max.toString()
    this.state.suggesteddestinations[pos].tempmin = data.main.temp_min.toString()
    this.state.suggesteddestinations[pos].feelslike = data.main.feels_like.toString()
    this.state.suggesteddestinations[pos].pressure = data.main.pressure.toString()
    this.state.suggesteddestinations[pos].windspeed = data.wind.speed.toString()
} 


apiCallForcast = async (name, pos) => {
    const apicall = await fetch(""+name +"&units=metric&APPID=5afdbd7139b98ae3f70a76b0dda2b43b")
    await apicall.json()
    .then(data =>
        this.formatForcast(data, pos)
    )
}

formatForcast = (data, pos) => {
    this.state.suggesteddestinations[pos].dayone = data.list[4]
    this.state.suggesteddestinations[pos].daytwo = data.list[12]
    this.state.suggesteddestinations[pos].daythree = data.list[20]
    this.state.suggesteddestinations[pos].dayfour = data.list[28]
    this.state.suggesteddestinations[pos].dayfive = data.list[36]
}


render (){
    console.log(this.state.suggesteddestinations)
    console.log(this.state.loaded)
    if (this.state.loaded) return null;
    return(
        <div>
            <BrowserRouter>
                <div className="container">
                    <Header />
                    {/* <Route path="/" render={(props) =>
                        <Home {...props} suggesteddestinations={this.state.suggesteddestinations} />
                    } /> */}
                    <Route path="/home" component = {Home} exact />
                    <Route path="/CurrentWeather/:id" component = {CurrentWeather} />
                    <Route path="/EventSelection/:id" component = {EventSelection} />
                    <Route path="/Schedule" component = {Schedule} />
                </div>
            </BrowserRouter>
        </div>
    )
}

}

1 Answer

There are a few issues in the code , State cannot be mutated meaning this.state cannot be set outside the constructor.The other issue is the code is over-engineered :) Since you are learning react I would recommend that you understand how State Management / Props / Component life cycle methods from the react documentation

Nice try!

Here is the actual refactored code :

import React,{Component} from 'react'

export default class StackApp60663913 extends Component {
    state = {
        suggesteddestinations : [],
        scheduleddestinations : [],
        loaded: false
    }


    componentDidMount = () =>{
        this.grabData()
    }

    grabData = async () =>{
        let suggestionsApi = "";

        let suggestionFetch = await fetch(suggestionsApi)
        let suggestionData = await suggestionFetch.json()   

        for (let index = 0; index < suggestionData.length; index++) {
            let city = suggestionData[index]

            let weatherFetch = await fetch(`)   
            let weatherData = await weatherFetch.json()

            let {main,weather,clouds,wind,sys} = weatherData.list[0]

            suggestionData[index].temp = main.temp.toString()
            suggestionData[index].desc = weather[0].description
            suggestionData[index].tempmax = main.temp_max.toString()
            suggestionData[index].tempmin = main.temp_min.toString()
            suggestionData[index].feelslike = main.feels_like.toString()
            suggestionData[index].pressure = main.pressure.toString()
            suggestionData[index].windspeed = wind.speed.toString()

        }

        this.setState({
            suggesteddestinations : suggestionData,
            loaded:true            
        })

    }    

    render (){
        console.log(this.state.suggesteddestinations)
        return(
            <div>
                {this.state.loaded ? 
                <div>
                    {
                        this.state.suggesteddestinations.map((element)=>
                        <li>
                           ID-{element.id},Name-{element.name},Temp-{element.temp},Desc-{element.desc},TempMin-{element.tempmin},TempMax-{element.tempmax} 
                        </li>)
                    }
                </div> :  <div>Loading Data...</div>
                }
            </div>
        )
    }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Elena Rostova

Elena Rostova

Lead Health, Wellness & Medical Journalist

Elena Rostova holds a Master's degree in Public Health Journalism. She covers groundbreaking medical research, holistic wellness trends, mental health awareness, and nutritional science.

Share this article
Twitter Facebook Pinterest