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

Commit b235b10

Browse files
authored
Merge pull request #127 from reasonml-community/feat/mutation-error-policy
Feat/mutation error policy
2 parents a51516f + 57171e3 commit b235b10

File tree

3 files changed

+56
-20
lines changed

3 files changed

+56
-20
lines changed

README.md

+25-18
Original file line numberDiff line numberDiff line change
@@ -182,22 +182,34 @@ module ScreamMutation = [%graphql {|
182182
[@react.component]
183183
let make = () => {
184184
/* Both variant and records available */
185-
let ( screamMutation, _simple, _full ) = useMutation(~variables=ScreamMutation.makeVariables(~screamLevel=10, ()), ScreamMutation.definition);
185+
let ( screamMutation, simple, _full ) =
186+
useMutation(~variables=ScreamMutation.makeVariables(~screamLevel=10, ()), ScreamMutation.definition);
186187
let scream = (_) => {
187188
screamMutation()
188-
|> Js.Promise.then_(result => {
189-
switch(result) {
190-
| Data(data) => ...
191-
| Error(error) => ...
192-
| NoData => ...
193-
}
194-
Js.Promise.resolve()
195-
})
189+
|> Js.Promise.then_(((simple, _full)) => {
190+
// Trigger side effects by chaining the promise returned by screamMutation()
191+
switch (simple) {
192+
// You *must* set the error policy to be able to handle errors
193+
// in then_. See EditPersons.re for more
194+
| ApolloHooks.Mutation.Errors(_theErrors) => Js.log("OH NO!")
195+
| NoData => Js.log("NO DATA?")
196+
| Data(_theData) => Js.log("DATA!")
197+
};
198+
Js.Promise.resolve();
199+
})
196200
|> ignore
197201
}
198202
203+
// Use simple (and/or full) for (most) UI feedback
199204
<div>
200-
<button onClick={scream}>
205+
{switch (simple) {
206+
| NotCalled
207+
| Data(_) => React.null
208+
| Loading => <div> "Screaming!"->React.string </div>
209+
| NoData
210+
| Error(_) => <div> "Something went wrong!"->React.string </div>
211+
}}
212+
<button onClick={scream} disabled={simple === Loading}>
201213
{React.string("You kids get off my lawn!")}
202214
</button>
203215
</div>
@@ -213,14 +225,9 @@ let make = () => {
213225
let ( screamMutation, _simple, _full ) = useMutation(ScreamMutation.definition);
214226
let scream = (_) => {
215227
screamMutation(~variables=ScreamMutation.makeVariables(~screamLevel=10, ()), ())
216-
|> Js.Promise.then_(result => {
217-
switch(result) {
218-
| Data(data) => ...
219-
| Error(error) => ...
220-
| NoData => ...
221-
}
222-
Js.Promise.resolve()
223-
})
228+
|> Js.Promise.then_(((simple, _full)) => {
229+
...
230+
})
224231
|> ignore
225232
}
226233

examples/persons/src/EditPerson.re

+25-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ let make = (~refetchQueries, ~update) => {
7171
React.useReducer(reducer, {age: None, name: "", id: ""});
7272

7373
let (editPersonMutation, _simple, _full) =
74-
useMutation(~refetchQueries, ~update, EditPersonMutation.definition);
74+
useMutation(
75+
~refetchQueries,
76+
~update,
77+
~errorPolicy=All, // See note below on error policies
78+
EditPersonMutation.definition,
79+
);
7580

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

src/ApolloHooksMutation.re

+6
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ type options('a) = {
6464
[@bs.optional]
6565
optimisticResponse: Js.Json.t,
6666
[@bs.optional]
67+
errorPolicy: string,
68+
[@bs.optional]
6769
context: Context.t,
6870
};
6971

@@ -97,6 +99,7 @@ let useMutation:
9799
unit
98100
=?,
99101
~optimisticResponse: Js.Json.t=?,
102+
~errorPolicy: ApolloHooksTypes.errorPolicy=?,
100103
~context: Context.t=?,
101104
ApolloHooksTypes.graphqlDefinition('data, _, _)
102105
) =>
@@ -112,6 +115,7 @@ let useMutation:
112115
~awaitRefetchQueries=?,
113116
~update=?,
114117
~optimisticResponse=?,
118+
~errorPolicy=?,
115119
~context=?,
116120
(parse, query, _),
117121
) => {
@@ -125,6 +129,8 @@ let useMutation:
125129
~awaitRefetchQueries?,
126130
~update?,
127131
~optimisticResponse?,
132+
~errorPolicy=?
133+
errorPolicy->Belt.Option.map(ApolloHooksTypes.errorPolicyToJs),
128134
~context?,
129135
(),
130136
),

0 commit comments

Comments
 (0)