Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Commit

Permalink
Merge pull request #127 from reasonml-community/feat/mutation-error-p…
Browse files Browse the repository at this point in the history
…olicy

Feat/mutation error policy
  • Loading branch information
mbirkegaard authored Jun 20, 2020
2 parents a51516f + 57171e3 commit b235b10
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 20 deletions.
43 changes: 25 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,22 +182,34 @@ module ScreamMutation = [%graphql {|
[@react.component]
let make = () => {
/* Both variant and records available */
let ( screamMutation, _simple, _full ) = useMutation(~variables=ScreamMutation.makeVariables(~screamLevel=10, ()), ScreamMutation.definition);
let ( screamMutation, simple, _full ) =
useMutation(~variables=ScreamMutation.makeVariables(~screamLevel=10, ()), ScreamMutation.definition);
let scream = (_) => {
screamMutation()
|> Js.Promise.then_(result => {
switch(result) {
| Data(data) => ...
| Error(error) => ...
| NoData => ...
}
Js.Promise.resolve()
})
|> Js.Promise.then_(((simple, _full)) => {
// Trigger side effects by chaining the promise returned by screamMutation()
switch (simple) {
// You *must* set the error policy to be able to handle errors
// in then_. See EditPersons.re for more
| ApolloHooks.Mutation.Errors(_theErrors) => Js.log("OH NO!")
| NoData => Js.log("NO DATA?")
| Data(_theData) => Js.log("DATA!")
};
Js.Promise.resolve();
})
|> ignore
}
// Use simple (and/or full) for (most) UI feedback
<div>
<button onClick={scream}>
{switch (simple) {
| NotCalled
| Data(_) => React.null
| Loading => <div> "Screaming!"->React.string </div>
| NoData
| Error(_) => <div> "Something went wrong!"->React.string </div>
}}
<button onClick={scream} disabled={simple === Loading}>
{React.string("You kids get off my lawn!")}
</button>
</div>
Expand All @@ -213,14 +225,9 @@ let make = () => {
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()
})
|> Js.Promise.then_(((simple, _full)) => {
...
})
|> ignore
}
Expand Down
27 changes: 25 additions & 2 deletions examples/persons/src/EditPerson.re
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ let make = (~refetchQueries, ~update) => {
React.useReducer(reducer, {age: None, name: "", id: ""});

let (editPersonMutation, _simple, _full) =
useMutation(~refetchQueries, ~update, EditPersonMutation.definition);
useMutation(
~refetchQueries,
~update,
~errorPolicy=All, // See note below on error policies
EditPersonMutation.definition,
);

let handleSubmit = event => {
ReactEvent.Form.preventDefault(event);
Expand All @@ -89,8 +94,26 @@ let make = (~refetchQueries, ~update) => {
OptimisticResponse.make(~id=state.id, ~name=state.name, ~age),
(),
)
/* Setting error policy to All (or Ignore) means that errors show up
* in then_ in the promise returned by editPersonMutation
* Not setting it (or setting it to None) makes the promise reject
* on errors and you'll have to handle errors in Js.catch(e => ...) instead,
* where e is just Js.Promise.error and you won't get any help from the type system.
*
* See also: https://www.apollographql.com/docs/react/data/error-handling/#error-policies
*/
|> Js.Promise.then_(((simple, _full) as result) => {
switch (simple) {
| ApolloHooks.Mutation.Errors(_theErrors) => Js.log("OH NO!")
| NoData => Js.log("NO DATA?")
| Data(_theData) => Js.log("DATA!")
};
// If you don't need to handle the result elsewhere,
// the promise can just resolve to unit
Js.Promise.resolve(result);
})
|> ignore
| None => ignore()
| None => ()
};
};

Expand Down
6 changes: 6 additions & 0 deletions src/ApolloHooksMutation.re
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ type options('a) = {
[@bs.optional]
optimisticResponse: Js.Json.t,
[@bs.optional]
errorPolicy: string,
[@bs.optional]
context: Context.t,
};

Expand Down Expand Up @@ -97,6 +99,7 @@ let useMutation:
unit
=?,
~optimisticResponse: Js.Json.t=?,
~errorPolicy: ApolloHooksTypes.errorPolicy=?,
~context: Context.t=?,
ApolloHooksTypes.graphqlDefinition('data, _, _)
) =>
Expand All @@ -112,6 +115,7 @@ let useMutation:
~awaitRefetchQueries=?,
~update=?,
~optimisticResponse=?,
~errorPolicy=?,
~context=?,
(parse, query, _),
) => {
Expand All @@ -125,6 +129,8 @@ let useMutation:
~awaitRefetchQueries?,
~update?,
~optimisticResponse?,
~errorPolicy=?
errorPolicy->Belt.Option.map(ApolloHooksTypes.errorPolicyToJs),
~context?,
(),
),
Expand Down

0 comments on commit b235b10

Please sign in to comment.