There is a config data in project which is used by multiple components and services. The idea is to build a service which gets just once the data from API and provides it cached every time is needed.
private getConfig(): Observable<InitConfig> {
return this.http.get('public/config/initconfig')
.pipe(
tap((config: InitConfig) => {
this.config = config; // set the config
}),
);
}
public getInitConfig(): Observable<InitConfig> {
if ( _.isEmpty(this.config) ) {
return this.getConfig();
} else {
return of(this.config);
}
}
The problem is when the get request is on progress and the data is not cached yet. If another consumer calls getInitConfig() at this time I get duplicated get request.
You need a private observable that indicates if the config was already fetched, if it wasn't (which means it's the first subscription) initialize it and either way return it.
First, add a private config$: Observable<InitConfig> to your service.
Next, use shareReplay(1) in order to share the result among the subscribers.
It should look something like this:
private config$: Observable<InitConfig>;
getInitConfig(): Observable<InitConfig> {
if (!this.config$) {
this.config$ = this.http
.get("https://jsonplaceholder.typicode.com/users/1")
.pipe(
tap(() => console.log("config fetched")),
shareReplay(1)
);
}
return this.config$;
}
You can test it by subscribing multiple times and see config fetched being logged only once:
ngOnInit(): void {
this.configService.getInitConfig().subscribe(() => console.log('Config Subscription - 1'))
this.configService.getInitConfig().subscribe(() => console.log('Config Subscription - 2'))
this.configService.getInitConfig().subscribe(() => console.log('Config Subscription - 3'))
}
You can see the full code in this stackblitz
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With