3

Why is data undefined in Promise even though it appears in html below?

I dont want to use .then((data) =>

const LoginPage: React.SFC<{}> = () => {
    const [login, { loading, data, error }] = useMutation<Q, V>(MUTATION)

    const onSubmit = event => {
        event.preventDefault()
        login({
            variables: {
                email,
                password
            }
        }).then(() => {
            console.log(data)         // <-- undefined
        }).catch(() => {
            console.log(error)        // <-- OK
        })
    }

    return <div>
        <form onSubmit={onSubmit}> ... </form>

        {data && <pre>{JSON.stringify(data)}</pre>}          //  <-- OK
    </div>
}
AHOYAHOY
  • 1,856
  • 4
  • 24
  • 34

2 Answers2

2

A variation of the original question. Not sure if it works as intended though because the result of the mutation's Promise is undefined. Thanks.

        const [login] = useMutation(MUTATION);

        const onSubmit = event => {
            event.preventDefault()
            login({
                variables: {
                    email,
                    password
                }
            }).then((result) => {
                console.log(result)       // <-- undefined
            }).catch(() => {
                console.log(error)        // <-- OK
            })
        }
Thien Pham
  • 21
  • 2
1

This is working as intended. The state update caused by calling the state updater function returned by a useState hook is asynchronous. useState is used under the hood by useMutation to manage the various bit of state returned by the hook (data, loading, error, etc.) so this state will also update asynchronously. This means the Promise returned by login can resolve, and in doing so, the appropriate state will be updated, just not immediately. Once it is updated, the component is rerendered and you see the updated value rendered in your component.

If you need to utilize the data returned by the mutation in some way as soon as the Promise resolves, then you need to do so by extracting it from the resolved value of the Promise instead of relying on the component state.

Daniel Rearden
  • 80,636
  • 11
  • 185
  • 183