Server Side Rendering (SSR)
When using Server Side Rendering you would want to avoid double data load for same page. To atchieve this you have to do two steps:
Save state when on server
Load state when on browser
this can be attchieved in your app.module.ts
like:
export class AppModule {
private transferStateKey = makeStateKey(TRANSFER_STATE_KEY);
constructor(
private store: Store<MarketplaceState>,
private platform: PlatformService,
private transferState: TransferState,
private dataStrategy: DataStrategy,
) {
if (!this.platform.isBrowser) {
this.saveState();
} else {
this.loadState();
}
}
private saveState() {
this.store.pipe(takeWhile(() => !this.platform.isBrowser)).subscribe((state) => {
this.transferState.set(this.transferStateKey, this.dataStrategy.toJS(state));
});
}
private loadState() {
if (!this.transferState.hasKey(this.transferStateKey)) {
return;
}
const state = this.transferState.get(this.transferStateKey, {} as any);
this.store.update((s) => {
this.dataStrategy.merge(s, state, [], true);
s.dataRestoredFromSSR = true;
});
this.removeRestoredFromSSRFlag();
}
private removeRestoredFromSSRFlag() {
document.addEventListener('readystatechange', (event: any) => {
if (event.target.readyState === 'complete') {
this.store.update((s) => {
s.dataRestoredFromSSR = false;
});
document.removeEventListener('readystatechange', (_) => {});
}
});
}
}
Lets break this code
saveState
method saves all state changes until on serverloadState
method checks if saved state exists and if so loads it and merges onto the store and setsdataRestoredFromSSR
to true. After we listen to page finish loading event in order to setdataRestoredFromSSR
back to false.
Our http requests might look like this
this.http.post(url, body).pipe(
withLatestFrom(this.store.map((s) => s.dataRestoredFromSSR)),
filter(([_, dataRestoredFromSSR]) => !dataRestoredFromSSR),
map(([response, _]) => response),
//do the rest like .subscribe
)
Last updated
Was this helpful?