-
-
Save jonnysamps/0dfa5ecaea13677e7b2fabe538720567 to your computer and use it in GitHub Desktop.
Apollo Client Best Practices - 1
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
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