To reduce network traffic I need to check if the entity with the given id is in the store and if not, it should be requested from the server. I couldn't find any configuration for that, so I just hard coded the logic using RxJs like below.
Is there a way to configure that with NgRx/NgRx data? Is there a way to configure how long can an entity be in the store without need to rerequest?
import {
EntityCollectionServiceBase,
EntityCollectionServiceElementsFactory,
} from '@ngrx/data';
import { Injectable } from '@angular/core';
import { MyEntity } from 'app/state/my-entity/MyEntity';
import { Observable, of, Subject } from 'rxjs';
import { distinct, filter, switchMap, tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class MyEntityDataService extends EntityCollectionServiceBase<MyEntity> {
private id$ = new Subject<string|number>();
constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
super('MyEntity', serviceElementsFactory);
// Fetching the data if not yet there
this.id$.pipe(
// Preventing multiple requests e.g. when multiple components
// are requesting the same data
distinct(),
switchMap(
(id: string|number): Observable<MyEntity | undefined> => this.filteredEntities$.pipe(
switchMap(
(entityCollection: MyEntity[]): Observable<MyEntity | undefined> => {
const thatEntity: MyEntity | undefined =
entityCollection.find((entity: MyEntity) => `${entity.id}` === `${id}`);
return of(thatEntity).pipe(
filter((v: MyEntity | undefined): boolean => !v),
tap(() => super.getByKey(id))
)
}
),
),
),
).subscribe();
}
getByKey(id: string|number): Observable<MyEntity> {
this.id$.next(id);
return this.filteredEntities$.pipe(
switchMap(
(entityCollection: MyEntity[]) : Observable<MyEntity> => {
const thatEntity: MyEntity | undefined = entityCollection.find(
(entity: MyEntity) => `${entity.id}` === `${id}`
);
return thatEntity ? of(thatEntity) : of();
}
),
);
}
}
I faced the same problem and the best solution for me was to check it on the effect before dispatch the action.
if you want to make sure to fetch data even if there is data on the store simply dispatch
findbyIdaction instead