Search code examples
javascriptreactjsfetchuse-effect

Code is moving on before my fetch is completed


I'm having a problem where inside my useEffect whenever I call getRoomDetails, the code continues on before it's finished fetching data from my API. So it will create the Chess object with the default value I've given for boardState, instead of the updated value from my API. How could I get it so it waits until getRoomDetails finishes, before moving onto creating the Chess object.

    const initialState = {
    hostTime: 600,
    guestTime: 600,
    chessAnnotations: "",
    isHost: true,
    fen: "start",
}

const getRoomDetails = () => {
    fetch('/api/get-room?code=' + roomCode).then((response) =>
        response.json()
    ).then((data) => {
        const newObj = {
            hostTime: data.host_curr_time,
            guestTime: data.guest_curr_time,
            chessAnnotations: data.chess_annotations,
            isHost: data.is_host,
            fen: data.fen,
        };
        setBoardState(newObj);
        console.log(newObj)
    });
}

const [boardState, setBoardState] = useState(initialState);


let game = useRef(null);
useEffect(() => {
    getRoomDetails();
    console.log(boardState.fen + "lit");
    game.current = new Chess(boardState.fen);
    console.log("0");
}, []);

Output:

start 0
0
Object { hostTime: "600.00", guestTime: "600.00", chessAnnotations: "sdf", isHost: false, fen: "rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq - 0 1" }

Solution

  • See the explanation in the inline comments

    const initialState = {
        hostTime: 600,
        guestTime: 600,
        chessAnnotations: "",
        isHost: true,
        fen: "start",
    }
    
    const getRoomDetails = () => {
      // HERE:  Return the promise
        return fetch('/api/get-room?code=' + roomCode).then((response) =>
            response.json()
        ).then((data) => {
            const newObj = {
                hostTime: data.host_curr_time,
                guestTime: data.guest_curr_time,
                chessAnnotations: data.chess_annotations,
                isHost: data.is_host,
                fen: data.fen,
            };
            setBoardState(newObj);
            console.log(newObj)
        });
    }
    
    const [boardState, setBoardState] = useState(initialState);
    
    
    let game = useRef(null);
    useEffect(() => {
        getRoomDetails()
        // HERE: run this block after the promise is resolved
        .then(() => {
            console.log(boardState.fen + "lit");
            game.current = new Chess(boardState.fen);
            console.log("0");
        });
    }, []);