5
5
[ ![ semantic-release] ( https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg )] ( https://github.com/semantic-release/semantic-release )
6
6
[ ![ Commitizen friendly] ( https://img.shields.io/badge/commitizen-friendly-brightgreen.svg )] ( http://commitizen.github.io/cz-cli/ )
7
7
8
- Handling Apollo cache updates after creating and deleting objects remains a
8
+ Handling Apollo cache updates after creating and deleting objects, or
9
+ associating and dissociating objects, remains a
9
10
[ poorly solved problem] ( https://github.com/apollographql/apollo-client/issues/899 ) .
10
11
` update ` and ` refetchQueries ` props on ` Mutation ` s couple different areas of
11
12
your app in a way you probably don't want, and they don't scale well as you add
@@ -16,6 +17,19 @@ and cache code.
16
17
17
18
Until that happens, this is probably your best bet!
18
19
20
+ # Table of Contents
21
+
22
+ * [ How it works] ( #how-it-works )
23
+ * [ Current limitations] ( #current-limitations )
24
+ * [ ES environment requirements] ( #es-environment-requirements )
25
+ * [ Type metadata usage] ( #type-metadata-usage )
26
+ * [ Handling Deletions] ( #handling-deletions )
27
+ * [ Handling Creation] ( #handling-creation )
28
+ * [ Handling associations being broken] ( #handling-associations-being-broken )
29
+ * [ Handling associations being created] ( #handling-associations-being-created )
30
+ * [ API] ( #api )
31
+ + [ ` refetch(client, typename, [ids], [idField]) ` ] ( #refetchclient-typename-ids-idfield )
32
+
19
33
## How it works
20
34
21
35
After you delete an object, you tell ` apollo-magic-refetch ` what ` typename ` and
@@ -140,6 +154,154 @@ const CreateDeviceFormContainer = () => (
140
154
)
141
155
```
142
156
157
+ ## Handling associations being broken
158
+
159
+ In this example, a view shows a list of ` Organization ` s, each containing a
160
+ sublist of ` User ` s. When one or more users is removed from an organization,
161
+ it makes the following call:
162
+ ``` js
163
+ refetch (client, [
164
+ [' User' , userIds],
165
+ [' Organization' , organizationId],
166
+ ])
167
+ ```
168
+ Passing an array to ` refetch ` means to only refetch queries containing all of
169
+ the conditions in the array. So the query below would be refetched, but a query
170
+ containing only ` Organizations ` or a query containing only ` User ` s would not.
171
+
172
+ ``` js
173
+ import * as React from ' react'
174
+ import gql from ' graphql-tag'
175
+ import refetch from ' apollo-magic-refetch'
176
+ import {Mutation , ApolloConsumer } from ' react-apollo'
177
+ import OrganizationView from ' ./OrganizationView'
178
+
179
+ const query = gql `
180
+ query {
181
+ Organizations {
182
+ id
183
+ name
184
+ Users {
185
+ id
186
+ username
187
+ }
188
+ }
189
+ }
190
+ `
191
+
192
+ const mutation = gql `
193
+ mutation removeUsersFromOrganization ($organizationId : Int ! , $userIds : [Int ! ]! ) {
194
+ result : removeUsersFromOrganization (organizationId : $organizationId , userIds : $userIds ) {
195
+ organizationId
196
+ userIds
197
+ }
198
+ }
199
+ `
200
+
201
+ const OrganizationViewContainer = ({organization: {id, name, Users}}) => (
202
+ < ApolloConsumer>
203
+ {client => (
204
+ < Mutation
205
+ mutation= {mutation}
206
+ update= {(cache , {data: {result: {organizationId, userIds}}}) =>
207
+ refetch (client, [
208
+ [' User' , userIds],
209
+ [' Organization' , organizationId],
210
+ ])
211
+ }
212
+ >
213
+ {removeUsersFromOrganization => (
214
+ < OrganizationView
215
+ organization= {organization}
216
+ onRemoveUsers= {userIds => removeUsersFromOrganization ({
217
+ variables: {organizationId, userIds},
218
+ })}
219
+ / >
220
+ )}
221
+ < / Mutation>
222
+ )}
223
+ < / ApolloConsumer>
224
+ )
225
+
226
+ const OrganizationsViewContainer = () => (
227
+ < Query query= {query}>
228
+ {({data}) => {
229
+ const {Organizations } = data || {}
230
+ if (! Organizations) return < div / >
231
+ return (
232
+ < div>
233
+ < h1> Organizations< / h1>
234
+ {Organizations .map ((organization ) => (
235
+ < OrganizationViewContainer
236
+ key= {organization .id }
237
+ organization= {organization}
238
+ / >
239
+ )}
240
+ < / div>
241
+ )
242
+ }}
243
+ < / Query>
244
+ )
245
+ ` ` `
246
+
247
+ ## Handling associations being created
248
+
249
+ Assuming the same ` Organization` s/` User` s schema as above, the example performs
250
+ the necessary refetches when a user is created and added to an organization:
251
+ ` ` ` js
252
+ refetch (client, [
253
+ [' User' ],
254
+ [' Organization' , organizationId],
255
+ ])
256
+ ` ` `
257
+ In this case no ` ids` are given for ` User` , so any query containing the an
258
+ ` Organization` with the given ` organizationId` in its results and selecting any
259
+ ` User` s would be refetched. (This doesn't perfectly exclude cases that fetch
260
+ Users and Organizations separately, instead of one nested inside the other, but
261
+ it's better than nothing).
262
+
263
+ ` ` ` js
264
+ import * as React from ' react'
265
+ import gql from ' graphql-tag'
266
+ import refetch from ' apollo-magic-refetch'
267
+ import {Mutation , ApolloConsumer } from ' react-apollo'
268
+ import CreateUserForm from ' ./CreateUserForm'
269
+
270
+ const mutation = gql `
271
+ mutation createUser ($organizationId : Int ! , $values : CreateUser ! ) {
272
+ result : createUser (organizationId : $organizationId , values : $values ) {
273
+ organizationId
274
+ id
275
+ username
276
+ }
277
+ }
278
+ `
279
+
280
+ const CreateUserFormContainer = ({organizationId}) => (
281
+ < ApolloConsumer>
282
+ {client => (
283
+ < Mutation
284
+ mutation= {mutation}
285
+ update= {() =>
286
+ refetch (client, [
287
+ [' User' ],
288
+ [' Organization' , organizationId],
289
+ ])
290
+ }
291
+ >
292
+ {createUser => (
293
+ < CreateUserForm
294
+ onSubmit= {values => createUser ({
295
+ variables: {organizationId, values},
296
+ })}
297
+ / >
298
+ )}
299
+ < / Mutation>
300
+ )}
301
+ < / ApolloConsumer>
302
+ )
303
+ ` ` `
304
+
143
305
## API
144
306
145
307
### ` refetch (client, typename, [ids], [idField])`
@@ -150,9 +312,12 @@ const CreateDeviceFormContainer = () => (
150
312
151
313
The ` ApolloClient` in which to scan active queries.
152
314
153
- ##### ` typename : string`
315
+ ##### ` typenameOrTerms : string | Array < Term > `
154
316
155
- The ` __typename ` of the GraphQL type that was created or deleted.
317
+ The ` __typename` of the GraphQL type that was created or deleted, or an array of
318
+ ` [typename, ids, idField]` tuples (` ids` and ` idField` are optional). If an
319
+ array is given, a query must match all of the conditions in the array to be
320
+ refetched.
156
321
157
322
##### ` ids: any (* optional* )`
158
323
0 commit comments