0

Fetch is successful in below code (I have confirmed by looking at console - Network in browser) but the setState is not updating the allWeights array in state with the array of documents from MongoDB returned by API. When I use console.log() it prints what api returns but just setState is not working. I understand when render() executes allWeights array will have no value however after componentDidMount executes allWeights must have value if setState behaves as expected. I have searched for solutions provided for similar issue but they are not helpful for my issue. As the setState is not working the map function in render() throws error. Kindly help. I am stuck with this for last 3 days.

import React, {Component} from "react";
//
class TeamWeightsMain extends Component {
    constructor(props) {
        super(props);
        this.state = {
            allWeights: []
        }
    }
//
    componentDidMount() {
        console.log(`Entered componentDidMount()`);
         fetch("http://localhost:8080/getallemployees")
        .then(response  => response.json())
        .then((data)      => { 
             this.setState( 
                 {allWeights : data}
            );       
        });
    }
//    
    render() {        
        console.log(`Entered render() - allWeights value now : ${this.state.allWeights.toString()   }`);
        if(this.state.allWeights !== undefined && this.state.allWeights.length > 0) {
            console.log(`this.state.allWeights.length: ${this.state.allWeights.length}`);
            console.log(`this.state.allWeights: ${this.state.allWeights}`);
            console.log(`this.state: ${this.state}`);
            return(
                <main>{
                    this.state.allWeights.map((emp,i) => {
                        return <div key={i}>
                            {emp.empName}
                            {emp.employeeWeights.map((weight,j) => { 
                                return <div key={j} className="indentWeight"> 
                                            Date: {new Date(weight.weighedOn).toLocaleDateString()}
                                            {' '}
                                            Weight: {weight.empWeight}
                                        </div>
                                    })}
                            </div>}
                        )
                }
                </main>)           
        } 
        else {            
            console.log(`Inside Not authorized : ${this.state.allWeights}`);
            return (
                <main>
                    <h2>Teamweights</h2>
                    <div className="indentWeights">
                    Sample text
                    </div>
                </main>
           )
        }
    }
}
//
export default TeamWeightsMain;
  • `[Object object]` is just what happens when you try to use an object as a string. If you parse it from JSON to a string manually `JSON.stringify(variable)` and log it, it will work. – Brian Thompson Jul 07 '21 at 17:05
  • You can also log the state slightly differently by passing multiple arguments instead of concatenating to a string. `console.log('this.state', this.state)` (with a comma). This will let it log as an object an not try to print it as a string. – Brian Thompson Jul 07 '21 at 17:08
  • Yes I understand, but is the state not actually updating? Or are you just not accessing it correctly? – Brian Thompson Jul 07 '21 at 17:15
  • Hi Brian, your suggestion works and when I log it i see the data returned by API. ``` componentDidMount() { console.log(`Entered componentDidMount()`); fetch("http://localhost:8080/getallemployees") .then(response => response.json()) .then((data) => { this.setState({ allWeights : JSON.stringify(data) }); }); } ``` but i am getting "Uncaught TypeError: this.state.allWeights.map is not a function" error. the flow of execution is render, compdidmount, render, render then this error. – Avinash Jul 07 '21 at 17:33
  • why is render executing one more time? Is there any error in code? – Avinash Jul 07 '21 at 17:34
  • 1
    What Brian means is to not stringify the data when setting state. He means that when you log out the data on the line `console.log(`this.state: ${this.state}`)` you will get the [Object object] issue. Either use `console.log('this.state', this.state)` or `console.log(`this.state: ${JSON.stringify(this.state)}`)` to see what the state looks like. You could also add a debugger line there instead to inspect the code in your browsers dev tools. I find that much easier than logging. Best luck! – DCardenas Jul 07 '21 at 17:57
  • Multiple renders is not an issue, components rerender any time state or props change as well as for the initial mount. @DCardenas is correct about what I was meaning for you to do. – Brian Thompson Jul 07 '21 at 18:05

0 Answers0