2
votes

I have a login component that when submitted, calls a login mutation and retrieves the user data.

When the user data is returned, I want to set the apollo client state but I am confused by the docs on how to do so:

My component looks as so:

const LOGIN = gql`
  mutation login($username: String!, $password: String!) {
    login(username: $username, password: $password) {
      username
      fullName
    }
  }
`

const Login = () => {
  const onSubmit = (data, login) => {
    login({ variables: data })
      .then(response => console.log("response", response))
      .catch(err => console.log("err", err))
  }

  return (
    <Mutation 
        mutation={LOGIN}
        update={(cache, { data: { login } }) => {

      }}
    >
      {(login, data) => {

        return (
          <Fragment>
            {data.loading ? (
              <Spinner />
            ) : (
              <Form buttonLabel="Submit" fields={loginForm} onChange={() => {}} onSubmit={e => onSubmit(e, login)} />
            )}

            {data.error ? <div>Incorrect username or password</div> : null}
          </Fragment>
        )
      }}
    </Mutation>
  )
}

As you can see, I have the update prop in my mutation which receives the login param and has the user data which I want to set in the apollo client's state.

The example here writes the response to the cache cache.writeQuery but I am unsure if this is what I want to do. Would I not want to write to client (as opposed to cache) like they do in this example where they update the local data?

The update property of mutation only seems to receive the cache param so I'm not sure if there is any way to access client as opposed to cache.

How do I go about updating my apollo client state with the response of my mutation in the update property of mutate?

EDIT: my client:

const cache = new InMemoryCache()
const client = new ApolloClient({
  uri: "http://localhost:4000/graphql",
  clientState: {
    defaults: {
      locale: "en-GB",
      agent: null /* <--- update agent */
    },
    typeDefs: `
      enum Locale {
        en-GB
        fr-FR
        nl-NL
      }

      type Query {
        locale: Locale
      }
    `
  },
  cache
})
1
I don't understand what "state" you want to set, the examples you are linking to are for updating the client's cache for queries with cached data (that may now be invalid due to the mutation you perform). Are you trying to set some kind of auth context for future apollo-client queries after logging in?ed'
@EdwardSammutAlessi Yes I am trying to set the user data so that I can query it later on. Is it correct to write this to the client state then? If so, how do I achieve this?Stretch0
@Stretch0 There is no client state to write to. You need to store that information somewhere else. If you want to do something like add an Authentication header to your requests, look into using apollo-link to modify your requests before they are sent.ed'
@EdwardSammutAlessi maybe I am getting confused. I have added an edit with my client object and as you can see, I have my defaults where agent is equal to null. When a user logs in, I want agent to then get set. So do I want to be updating cache or client?Stretch0

1 Answers

4
votes

Using Context API

If you have wrapped your component somewhere higher up in the hierarchy with ApolloProvider

  • Using ApolloConsumer

    const Login = () => {
        const onSubmit = async (data, login, client) => {
            const response = await login({ variables: data });
    
            if (response) {
                client.whatever = response;
            }
        };
    
        return (
            <ApolloConsumer>
                {client => (
                    <Mutation mutation={LOGIN}>
                        {login => <Form onSubmit={e => onSubmit(e, login, client)} />}
                    </Mutation>
                )}
            </ApolloConsumer>
        );
    };
    
  • Using withApollo

    const Login = client => {
        const onSubmit = async (data, login) => {
            const response = await login({ variables: data });
    
            if (response) {
                client.whatever = response;
            }
        };
    
        return (
            <Mutation mutation={LOGIN}>
                {login => <Form onSubmit={e => onSubmit(e, login)} />}
            </Mutation>
        );
    };
    
    withApollo(Login);
    

Without Context API

import { client } from "wherever-you-made-your-client";

and just reference it there