Skip to content

Instantly share code, notes, and snippets.

@jonnysamps
Last active February 24, 2021 23:47
Show Gist options
  • Save jonnysamps/0dfa5ecaea13677e7b2fabe538720567 to your computer and use it in GitHub Desktop.
Save jonnysamps/0dfa5ecaea13677e7b2fabe538720567 to your computer and use it in GitHub Desktop.
Apollo Client Best Practices - 1
class WidgetService {
constructor(private auth: AuthService, private apollo: Apollo){}
// 1. BAD PRACTICE: keeps a separate member variable as the
// subject that will get exposed to users
// of this class. This creates opportunity to simply
// call `next` whenever it is convenient instead of
// pipelining from the _source of truth_ observable to
// create the intended behavior. This creates
// misdirection away from the source of truth
// and makes your code far less reasonable.
private _widgets: BehaviorSubject<UserInvite[]> = new BehaviorSubject(null);
// 2. GOOD PRACTICE: memoize the observable
public get widgets$(): BehaviorSubject<Widget[]> {
if (!this._widgets.value) {
this.initWidgets$();
}
// 3. BAD PRACTICE: exposes a subject outside of the
// class where it could be manupulated. Creates
// speghetti code thats hard to understand/debug.
return this._widgets;
}
private initWidgets$(): void {
this.auth.isAuthenticated$
.pipe(
mergeMap((isAuthenticated: boolean) =>
// 4. Provides a default value and only
// initates the apollo query after
// the user has authenticated
iif(() => isAuthenticated,
this.apollo
.watchQuery({
query: gql`
// ...
`
})
.valueChanges.pipe(
map((result: any) => {
return result.data.widgets;
})
),
of([])
)
)
)
// 5. BAD PRACTICE: should not automatically
// subscribe to observables if you are not the
// intended client of the data. This will always fire
// the query regardless of whether the client has
// subscribed.
.subscribe((widgets) => {
this._widgets$.next(widets);
});
}
// Modifies the widget in some way. And needs to
// alert any subscribing code to the change in the
// widget list.
public pokeWidget(id: string) {
return this.apollo
.mutate({
mutation: `...`,
variables: {
code: id,
},
})
.pipe(
map((data) => {
// 6. BAD PRACTICE: modifying data by hand outside
// of the source of truth.
this._widgets$.next(
this._widgets$.value.filter(...)
);
})
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment