Home > Blockchain >  How to correctly wait for async function to finish before executing another function in typescript?
How to correctly wait for async function to finish before executing another function in typescript?

Time:10-29

I'm writing a react app with an api written in python with FastAPI.

This is what my code looks like:

export default function Menu() {
    const [abstracts, setAbstracts] = useState<Array<string>>([])
    const [abstractsId, setId] = useState<string>("")
    const [entities, setEntities] = useState<any>([])
    const [showMore, setShowMore] = useState<boolean>(false)
    const location = useLocation()
    const navigate = useNavigate();

    const fetchAbstracts = async () => {
        const response = await fetch("http://localhost:8000/data")
        const data = await response.json()
        setAbstracts(data.abstracts)
        setEntities(data.entities)
        setId(data._id)
    }

    const saveAbstracts = async () => {
        await fetchAbstracts()
        entities[location.state.id] = location.state.entities
        await fetch(`http://localhost:8000/data/${abstractsId}`, {
            method: "PUT",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ 'entities': entities })
        })
    }

    useEffect(() => {
        if (location.state.path == "/annotate") {
            saveAbstracts()
        } else {
            fetchAbstracts()
        }

    }, [])

My issue is when I try to send the data to the api, using the saveAbstracts function abstractsId is empty, so I get the following error:

enter image description here

How can I solve this? Thanks.

CodePudding user response:

The thing about setState in ractjs is that they are asynchronous. So, when you call the await fetchAbstracts() inside of saveAbstracts it fetches the data and then calls setAbstracts and the component updates, but the context of that function did not change, so the new abstracts will not be there to use. A very simple solution to this could be just returning the data from the fetchAbstracts function as such:

const fetchAbstracts = async () => {
    const response = await fetch("http://localhost:8000/data")
    const data = await response.json()
    setAbstracts(data.abstracts)
    setEntities(data.entities)
    setId(data._id)
    return data;
}

const saveAbstracts = async () => {
    const data = await fetchAbstracts()
....
  • Related