'Services and fetching data only once
I just to make sure this is a good approach to what I am trying to do. I have a component and a service. The service is responsible for holding data for the component, as well as fetching it from an http api. Here's a snippet from the service:
private _sessionDirectories: string[] | null = null;
private sessionDirectories: ReplaySubject<string[]> = new ReplaySubject<string[]>(1);
sessionDirectories$ : Observable<string[]> = this.sessionDirectories.asObservable()
constructor(private getService: GetService,
private apiService: ApiEndPointsService) { }
hasSessionDirectories() : boolean {
return this._sessionDirectories !== null;
}
fetchSessionDir() : Observable<boolean> {
return this.getSessionDir().pipe(
tap(o => {
this._sessionDirectories = o;
this.sessionDirectories.next(o);
}),
map(() => true),
catchError(()=> of(false))
);
}
private getSessionDir() : Observable<string[]> {
return this.getService.get(this.apiService.getGetSessionDir()).pipe(
map((o : any) => o.directories),
shareReplay(1),
);
}
And here is a snippet from the component:
directories$: ReplaySubject<string[]> = new ReplaySubject<string[]>(1);
constructor(private sessionService: SessionService,
private router: Router,
private errorService: ErrorService) {
}
isLoaded : boolean = false;
ngOnInit(): void {
this.sessionService.sessionDirectories$.pipe(take(1)).subscribe(o =>{
console.log(o);
this.directories$.next(o);
this.isLoaded = true;
});
if (!this.sessionService.hasSessionDirectories()) {
this.sessionService.fetchSessionDir().subscribe(o => {
if (!o) {
this.errorService.updateMessage("Could not load sessions");
this.router.navigate(['error']);
}
});
}
}
So my questions are:
Given the way that I've written it, I guess using shareReplay(1) in getSessionDir() is kinda of pointless? Given that it is subscribed to only within the service (private method), and that there is only 1 subscriber as well.
Is the way that I have "tunnelled" up the error to the component a good way to do it?
That I've got _sessionDirectories, sessionDirectories, and sesssionDirectories$ just doesn't seem right to me. I introduced _sessionDirectories so that I can create a hasSessionDirectories() method, so that I only fetch once in the component. Ideally I'd have checked whether sessionDirectories$ has any values, and if so then don't do it. If I subscribe to this.sessionService.sessionDirectories$ within the constructor, the call back of the subscribe method isn't called - I guess because the "stream" of sessionDirectories$ is still empty. Ideally I would have done something like:
this.sessionService.sessionDirectories$.subscribe(o => {
if (!o) {
// code to fetch for the first time, but this isn't executed because sessionDirectorie$ is empty...
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
