-
Notifications
You must be signed in to change notification settings - Fork 28
controlledVariant type mismatch from useMutation promise result #101
Comments
Hey there! |
TL;DR That is the correct approach. When you write
are you doing something like?
Things are type checked a bit unintuituvely. Not from first line to last, but from inner to outer scope. It doesn't go "okay this is a promise with a certain type, so the thing after You can see this at work if you define a handler in an empty
This will give a compile error saying something like "The variant constructor Data can't be found.". If you
Prior to #95, the mutate function was (incorrectly) returning
That mean you could do In 6.0.0, the type of
To make this type check, you need to make sure that the compiler doesn't guess the |
@peterpme Did you see the explanation? Does it make sense?
It would be greatly appreciated if you added something to the README! |
@mbirkegaard Although your explanation is pretty complete and makes sense, we didn't managed to make it work. Even copy/pasting README examples gives compilation errors. This is highly frustrating because it's like we can't use the mutation hook at all. We tried typing result with both:
I did a bit of extra digging and the promise does not return result but a tuple
V6 mutations seems unusable for now 😞I can't find a way to use them other than hacking my way through using Help on this would be really appreciated. We could update the README later on when we understand how to make it work. (cc @WhyThat) |
After fighting some more, finally find a way to make it work that is not too heavy: let handleClick = _ => {
mutate(~variables=MyMutation.makeVariables(~simeVar=123, ()), ())
|> Js.Promise.then_((( result: ApolloHooksMutation.executionVariantResult('a), _ )) => {
switch(result) {
| Data(data) => Js.Console.log(data##insert_user)
| Errors(error) => Js.Console.log(error)
| _ => Js.Console.log("🤷")
};
Js.Promise.resolve();
})
|> ignore
} The key being, destructuring the tuple and focring the type of the part that interest you ( |
Hi all, just spent 3 hours fighting this too.. an update to the readme would be great! happy to assist. |
Yeah... unfortunately, between my explanation and your following message it was updated to return the
It would be greatly appreciated if you added something to the README! |
Will happily review a PR! |
Just in case anyone else gets stuck with this, a quick workaround is to use mutation(~variables=MyMutation.makeVariables(~stuff, ()), ())
-> Js.Promise.then_(( result: ApolloHooksMutation.result('a))=> {
switch(result) {
| ApolloHooks.Mutation.Data(_data) => ()
| Error(_error) => ()
| NoData => ()
};
Js.Promise.resolve(result);
}, _) |> ignore; This looks to be handled better with the new (simple, full) response type. |
Not sure if this has become stale at this point but I'm having a somewhat related issue that I can't find info for, here's my code: mutate(
~variables=SignInMutation.makeVariables(~email, ~password, ()),
(),
)
->Promise.Js.fromBsPromise
->Promise.Js.map(
((simple: Mutation.executionVariantResult('a), _)) => {
switch (simple) {
| Data(data) =>
let {user} = data##signIn;
switch (user.email, user.createdAt, user.updatedAt) {
| (Ok(email), Ok(createdAt), Ok(updatedAt)) =>
form.reset();
form.notifyOnSuccess(None);
User.make(~email, ~createdAt, ~updatedAt)
->UserContext.SignIn
->dispatch;
| _ => form.notifyOnFailure(UnexpectedServerError)
};
| NoData => form.notifyOnFailure(UnexpectedServerError)
| Errors(errors) =>
Js.Console.log2("This never logs");
form.notifyOnFailure(BadCredentials);
};
})
|> ignore;
},
); My problem is that whenever graphql responds with a ->Promise.Js.catch(error => {
Js.Console.log2("this does trigger", error);
Promise.Js.rejected(error);
}); My graphql mutations do respond with errors based on variables or wether things exist or nat and I would like to be able to sue |
@EnriqueVidal This doesn't look like it has to do with https://www.apollographql.com/docs/react/data/error-handling/#error-policies |
@mbirkegaard thanks for your quick reply I can see how to add that to I mean: vs: Am I' looking at the wrong files? |
You'll need to set it as the global default. Check the docs for |
@mbirkegaard thanks for responging, |
@mbirkegaard This is indeed not an issue with type defaultOptions = {
.
"query": {
.
"fetchPolicy": string,
"errorPolicy": string,
},
"mutate": {. "errorPolicy": string},
};
type apolloObjectParams = {
cache: ReasonApolloTypes.apolloCache,
link: ReasonApolloTypes.apolloLink,
ssrMode: bool,
defaultOptions,
};
[@bs.module "apollo-client"] [@bs.new]
external createApolloClient:
apolloObjectParams => ApolloClient.generatedApolloClient =
"ApolloClient"; Then I just used like:
I use my own function since I build the client differently based on wether I I'm doing it for server o browser; that did the trick for me, but I always get a little nervous writing bindings as I don't know if there was a legit reason for the Can you see a safer cleaner way to do this? or is it safe to just do this until all libraries catch up to their Js counterparts? |
That's the right approach. You could make See also #122. |
@EnriqueVidal You don't need to use the promise for mutations, something like:
|
@RawToast this is interesting although I having difficulty understanding this comment because of the conflicting documentation etc, in this example where is result coming from what wouldn't My previous example worked once I figured how to set the error-policy but I'm always down for dropping promises and simplifying would you mind elaborating on this? |
Yeah, signIn will just be What you're really interested in is Something like this using the readme example: [@react.component]
let make = () => {
/* Both variant and records available */
let ( _screamMutation, simple, _full ) = useMutation(ScreamMutation.definition);
let scream = (_) => {
screamMutation(~variables=ScreamMutation.makeVariables(~screamLevel=10, ()), ())
|> Js.Promise.then_(result => {
switch(result) {
| Data(data) => ...
| Error(error) => ...
| NoData => ...
}
Js.Promise.resolve()
})
|> ignore
}
<div>
<button onClick={scream}>
{React.string("You kids get off my lawn!")}
</button>
<div>
switch(simple) {
| ApolloHooksMutation.NoData => {React.null}
| NotCalled => {React.string("You haven't screamed")}
| Loading(_) => {React.string("You are about to scream")}
| Data(_) => {React.string("You screamed")}
| Error(_) => {React.string("You can't scream")}
}
</div>
</div>
} |
That works if you don't need side effects. If you need to call things like |
Closing due to no progress and having moved off topic. |
Hi
After upgrading to 6.0.0 I've been getting a whole ton of these. A user named light.wave was able to figure this out by annotating:
is this the right approach? if so can we add this to the README / examples? Happy to help. Thanks!!
The text was updated successfully, but these errors were encountered: