-
-
Save jonnysamps/44b89351e956b9ea454d52801f2e6ed0 to your computer and use it in GitHub Desktop.
Apollo Client Best Practices - 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class WidgetService { | |
constructor( | |
private auth: AuthService, | |
private apollo: Apollo, | |
) {} | |
// 1. We still have a memoized member variable | |
// but this time it is an Observable (not a subject) | |
// and it gets created from piplining from our | |
// sources. | |
private _widgets$: Observable<Widget[]>; | |
public get widgets$(): Observable<UserInvite[]> { | |
// 2. Memoize the observable so that it can get shared | |
// around the app | |
if (!this._widgets$) { | |
this._widgets$ = this.getWidgets$(); | |
} | |
return this._widgets$; | |
} | |
private getWidgets$(): Observable<UserInvite[]> { | |
return this.auth.isAuthenticated$.pipe( | |
// 3. User filter instead of `iif` so that we don't | |
// even trigger any subscriptions until | |
// we have real data. This is just my preference. | |
filter(isAuthenticated => isAuthenticated), | |
mergeMap(() => { | |
return this.getWidgetsWatchQuery().valueChanges; | |
}), | |
map((result: any) => { | |
return result.data.widgets | |
}), | |
// 4. Make this observable "hot" so that all | |
// subscribers get the same stream of data. | |
// The argument specifies how much history should | |
// be replayed (so `1` means only the most recent) | |
shareReplay(1) | |
); | |
} | |
// 5. New: memorize the "QueryRef" so that we can trigger | |
// manual refetches of the data if we want. See: | |
// `pokeWidget` below for an example. | |
private _widgetsWatchQuery: QueryRef<unknown, EmptyObject>; | |
private getWidgetsWatchQuery(): QueryRef<unknown, EmptyObject> { | |
if (!this._widgetsWatchQuery) { | |
this._widgetsWatchQuery = this.apollo.watchQuery({ | |
query: gql` | |
// ... | |
` | |
}); | |
} | |
return this._widgetsWatchQuery; | |
} | |
public pokeWidget(id: string) { | |
return this.apollo | |
.mutate({ | |
mutation: `...`, | |
variables: { | |
code: id, | |
}, | |
}) | |
.pipe( | |
map((data) => { | |
// 6. Trigger the query to refetch. | |
// This will automatically feed the newly | |
// fetched results into the existing pipeline | |
// and any existing subscriptions. | |
this._widgetsWatchQuery?.refetch(); | |
}) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment