Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Useing ApolloClient.useMutation() #51

Closed
idkjs opened this issue Sep 16, 2020 · 4 comments
Closed

Useing ApolloClient.useMutation() #51

idkjs opened this issue Sep 16, 2020 · 4 comments

Comments

@idkjs
Copy link
Contributor

idkjs commented Sep 16, 2020

I am trying to use onCompleted on useMutation. Maybe this is equivalent to some other method in the library?

This compiles but doesnt not look right and cause an invalid hook call error.

  let loginFn = () => {
    let variables: LoginUser.t_variables = {email: "me@me.com"};
    let _ =
      ApolloClient.React.useMutation(
        ~mutation=(module LoginUser),
        ~onCompleted=
          ({login}) => {
            Js.log2("TOKEN_LOGIN", login);
            let token =
              login.token
              ->Belt.Option.map(t => t)
              ->Belt.Option.getWithDefault("");
            Dom.Storage.(localStorage |> setItem("token", token));
            Dom.Storage.(localStorage |> setItem("userId", login.id));
          },
        LoginUser.serializeVariables(variables)->ignore,
        // variables
      )->ignore;
    ();
  };

error:

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.`

Being called like this since its the only way i can get it to compile:

module LoginUser = [%graphql
  {|
  mutation LoginUser($email: String!) {
    login(email: $email) {
      id
      token
    }
  }
|}
];
[@react.component]
let make = () => {
  let loginFn = () => {
    let variables: LoginUser.t_variables = {email: "me@me.com"};
    let _ =
      ApolloClient.React.useMutation(
        ~mutation=(module LoginUser),
        ~onCompleted=
          ({login}) => {
            Js.log2("TOKEN_LOGIN", login);
            let token =
              login.token
              ->Belt.Option.map(t => t)
              ->Belt.Option.getWithDefault("");
            Dom.Storage.(localStorage |> setItem("token", token));
            Dom.Storage.(localStorage |> setItem("userId", login.id));
          },
        variables->ignore,
      )->ignore;
    ();
  };
  <div>
    <p>
      <button onClick={_e => loginFn()}>
        "ApolloClient.React.useMutation"->React.string
      </button>
    </p>
  </div>;
};

Thank you in advance!
Super work here!

Also, how is the above function different from the following which works but doesnt have onCompleted as an option?

let logLogin = _ =>
  Client.instance.mutate(~mutation=(module LoginUser), {email: "me@me.com"})
  ->Promise.get(
      fun
      | {data: Some({login}), error: None} => {
          Js.log2("TOKEN_LOGIN", login);
          let token =
            login.token
            ->Belt.Option.map(t => t)
            ->Belt.Option.getWithDefault("");

          Dom.Storage.(localStorage |> setItem("token", token));
          Dom.Storage.(localStorage |> setItem("userId", login.id));
        }
      | {error} => Js.log2("Error: ", error),
    );
@jeddeloh
Copy link
Owner

jeddeloh commented Sep 16, 2020

It's number 2: "you might be breaking the rules of hooks". In the error it says "Hooks can only be called inside of the body of a function component", but here you're using a hook in the body of a plain function.

@jeddeloh
Copy link
Owner

jeddeloh commented Sep 16, 2020

And to answer how the two things are different, one is a hook and one is a method on the client (both do essentially the same thing). The hook has other args you can pass to it like onCompleted for some rare use-case, but ultimately, both executing the mutation that comes out of the hook and calling the method on the client return a promise. You would use the resolution of the promise to know when it is completed. I've never really had a use-case for useMutation, it feels like burden to me. I always do client.mutate.

@jeddeloh
Copy link
Owner

Also, please note you are not actually executing your mutation in your hook example. Please check out the apollo docs on how to use useMutation: https://www.apollographql.com/docs/react/data/mutations/

@idkjs
Copy link
Contributor Author

idkjs commented Sep 17, 2020

Thank you for taking the time to educate me, brother. Peace to you.

@idkjs idkjs closed this as completed Sep 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants