Skip to content

Instantly share code, notes, and snippets.

@jonnysamps
Last active February 24, 2021 23:56
Show Gist options
  • Save jonnysamps/44b89351e956b9ea454d52801f2e6ed0 to your computer and use it in GitHub Desktop.
Save jonnysamps/44b89351e956b9ea454d52801f2e6ed0 to your computer and use it in GitHub Desktop.
Apollo Client Best Practices - 2
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