0

I am trying to pull a jwt out of a loginUser mutation and store it in a variable then use the apollo-link to setContext of the header via "Authorization: Bearer ${token} for authentification as all my other mutations and queries require the token. I have been slamming the docs for days on Apollo Client(React) -v 3.3.20. I have been through all the docs and they show all these examples of client.readQuery & writeQuery which frankly seem to just refetch data? I don't understand how you actually pull the data out of the response and store it in a variable.

The response is being stored in the cache and I have no idea how to take that data and store it in a token variable as I stated above. Which remote queries I can just access the returned data via the data object from the useQuery hook, however on the useMutation hook data returns undefined. The only thing I could find on this on stack overflow was the my data type may be custom or non-traditional type but not sure if that is the problem.

[Cache in apollo dev tools][1]

[Mutation in apollo dev tools][2]

[Response in network tab][3]

Here is my ApolloClient config:

    const httpLink = createHttpLink({ uri: 'http://localhost:4000/',
                                  // credentials: 'same-origin' 
                                });

const authMiddleware = new ApolloLink((operation, forward) => {

  const token = localStorage.getItem('token');
  // add the authorization to the headers
   operation.setContext(({ headers = {} }) => ({
     headers: {
      ...headers,
      authorization: `Bearer ${token}` || null,
    }
  }));

  return forward(operation);
})

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: concat(authMiddleware, httpLink),
});

The header works obviously I just can't grab the token to pass so the header just sends Authorization: Bearer.

For the login I have this:

const LOGIN_USER = gql`
    mutation($data:LoginUserInput!) {
        loginUser(
            data: $data
        ) {
            user {
                id
                name
            }
            token
        }
    }
`;

 const [loginUser, { data, loading, error }] = useMutation(LOGIN_USER);


 if (loading) return 'Submitting...';
 if (error) return `Submission error! ${error.message}`;

Originally I was just calling

onClick={loginUser( { variables })}

For the login but onComplete never works and everywhere I look I see lots of posts about it with no solutions. So I tried slamming everything into a function that I then called with loginUser inside it:

const submit = async () => {
    loginUser({ variables})
    // const { user } = await client.readQuery({
    //     query: ACCESS_TOKEN,
    // })
    
    // console.log(`User : ${JSON.stringify(user)}`)
    const token = 'token';
    const userId = 'userId';
    // console.log(user);
    // localStorage.setItem(token, 'helpme');
    // console.log({data});
  
  }

At this point I was just spending hours upon hours just trying mindless stuff to potentially get some clue on where to go.

But seriously, what does that { data } in useMutation even do if it's undefined. Works perfectly fine for me to call data.foo from useQuery but useMutation it is undefined.

Any help is greatly appreciated. [1]: https://i.stack.imgur.com/bGcYj.png [2]: https://i.stack.imgur.com/DlzJ1.png [3]: https://i.stack.imgur.com/D0hb3.png

badCode
  • 11
  • 1
  • just pointing some things out: the links are not formatted properly, and using common tags like [javascript] helps to attract more views and answerers – I_love_vegetables Aug 04 '21 at 08:34
  • your close, you can see in the screens that the token is there, I think you just need better call back code, see here for some ideas https://stackoverflow.com/questions/59465864/handling-errors-with-react-apollo-usemutation-hook, also I suggest you set up the callbacks inside the mutation block if possible see vipin goyal answer for what I mean – Nigel Savage Aug 15 '21 at 18:10

0 Answers0