Problems with login using useMutation

I have the following login code but it is not returning the User object from the server

import React, { useState } from 'react';
import { useHistory } from "react-router-dom";
import { gql, useMutation } from '@apollo/client';
import PropTypes from 'prop-types';
import client from '../../client';

const LOGIN = gql`
    mutation login($usernameOrEmail: String!, $password: String!) {
        login(usernameOrEmail: $usernameOrEmail, password: $password) {
            user {
                id
                displayName
                avatar
            }
        }
    }
`;

export default function Login({ setUser }) {
    const [usernameOrEmail, setUsernameOrEmail] = useState();
    const [password, setPassword] = useState();

    const [login, data] = useMutation(LOGIN);
    const history = useHistory();

    const loginHandler = async e => {
        console.log("loginHandler()");
        e.preventDefault();
        login({ variables: { usernameOrEmail, password} });
//        console.log("data.login.user = ", data.login.user);
        console.log("login():data = ", data);
        setUser(data.login);
        history.push("/home");
    }

    return(
        <div className="login-wrapper">
            <h1>Please Log In</h1>
            <form onSubmit={loginHandler}>
                <label>
                    <p>Username or email</p>
                    <input type="text" onChange={e => setUsernameOrEmail(e.target.value)} />
                </label>
                <label>
                    <p>Password</p>
                    <input type="password" onChange={e => setPassword(e.target.value)} />
                </label>
                <div>
                    <button type="submit">Submit</button>
                </div>
            </form>
        </div>
    )
}

Login.propTypes = {
    setUser: PropTypes.func.isRequired
};

is producing the following output on the console :-

loginHandler()
index.js:31 login():data =  {called: false, loading: false, client: ApolloClient}called: falseclient: ApolloClient {defaultOptions: {…}, resetStoreCallbacks: Array(0), clearStoreCallbacks: Array(0), link: HttpLink, cache: InMemoryCache, …}loading: false[[Prototype]]: Object
App.js:44 data.login =  undefined

I have been trying to solve this on and off over a few weeks. I have been thinking it must be something quite simple, but have been able to find a solution. Hope you can help, if not I can provide full source code for client and server demonstrating the problem.

Many thanks in advance,

Aaron

Hey there, looks to me like you’re not waiting for the request to complete. Try await login(...).

@mindnektar - Sorry await login does not appear to make any difference.

I just realised you’re trying to read data from the useMutation call. That will only update on the component’s next render. At the point you’re logging data, you’re still in the current render, so data hasn’t updated yet. You can access the mutation response like this, though:

const { data } = await login({ variables: { usernameOrEmail, password} }); 
1 Like

Many thanks that seems to have solved it. I really don’t know why I did not try that earlier. I am now getting a double rendering of the login page which I was not before but that is probably due to external React logic in my App,js.