0

Below is my code snippet that doesn't work as intended. The thing is the first console.log in upper useEffect shows that in fact the array has length 1 and it contains an item BUT it doesn't pass the if check. I assume that console.log is somehow asynchronous and it sees the updated state but the if doesn't. In that case I'm not sure how would I wait for the state to update because I thought that useEffect REACTS ON updated stated. Thank you in advance.

const [roomsCurrent, setRoomsCurrent] = useState([]);

useEffect(() => {

    console.log(roomsCurrent);

    if (roomsCurrent.length != 0) {
        console.log(roomsCurrent.length);
    }

}, [roomsCurrent]);

useEffect(async () => {
    let roomData = [];

    if (rooms != null) {

        await Promise.all(rooms['rooms'].map(async (room) => {
            let result = await fetchRoomCurrent(room['room_identifier']);
            roomData.push({
                "room_identifier": room["room_identifier"],
                "display_name": room["display_name"],
                "temperature": result["temperature"],
                "humidity": result["humidity"],
                "pressure": result["pressure"],
                "thermostat_state": result["thermostat_state"],
                "dryer_state": result["dryer_state"]
            });
        })).then(setRoomsCurrent(roomData));
    }

}, [rooms]);

EDIT: rooms obj

{
"rooms": [
    {
        "display_name": "Living room",
        "room_identifier": "living_room"
    },
    {
        "display_name": "Bathroom",
        "room_identifier": "bathroom"
    },
    {
        "display_name": "Kitchen",
        "room_identifier": "kitchen"
    }
]
}

EDIT: Changed original code, still no luck. Not sure how to loop asynchronously through all the rooms and update after all the cycles have passed.

Kyatt
  • 305
  • 2
  • 7
  • 1
    `roomsCurrent != roomData` will always be true since `[] != []` is true. Please also share an example of `rooms`? – evolutionxbox Jan 14 '22 at 08:42
  • *"The thing is the first console.log in upper useEffect shows that in fact the array has length 1 and it contains an item BUT it doesn't pass the if check."* That's because the array's contents have changed between when you logged it and did the `if` and later when you expand it in the console. The reason for that is you've used an `async` function with `forEach`, so as of `setRoomsCurrent(roomData)`, `roomData` is empty and the `useEffect` runs and sees an empty array. **Later**, the asynchronous code runs and adds elements to it, but by then it's too late. Instead, your entire process... – T.J. Crowder Jan 14 '22 at 08:45
  • ...for filling in the rooms should be asynchronous, and only call `setRoomsCurrent` when it's finished. Using an `async` function with `forEach` is [almost always incorrect](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop). – T.J. Crowder Jan 14 '22 at 08:45
  • Like @evolutionxbox already mentioned: Your comparison of the rooms will always be true. Use this comparison instead: JSON.stringify(roomsCurrent) !== JSON.stringify(roomData) – HOERNSCHEN Jan 14 '22 at 08:53

0 Answers0