NgRx/Data how to set loaded flag for an entitiy on getWithQuery

1.2k Views Asked by At

I am currently using NgRx Data in my project to handle a news entity.
I have a resolver to check if the news entities loaded and then route to the /news page (where I show the news)

the resolver is listening to the loaded$ observablle if it is false he will call the getAll method to get the news and then set loaded to true.

however I implemented an infinite scroll and now only want to get the news by query with the .getWithQuery method. this is working fine but when I get the news by query the action dispatched:

"ngrx/data/get/many/success" is only changing the loading flag not the loaded flag. enter image description here

therefore the resolver never routes to the page. Is there any way how I could change the loaded flag after getWithQuery is done successfully? My resolver currently looks like this:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.newsEntityService.loaded$
  .pipe(
    tap(loaded => {
      if (!loaded) {
        this.newsEntityService.getAll(); // <-- here I want to call .getWithQuery(queryParams)
      }
    }),
    filter(loaded => !!loaded),
    first()
  );

}

I tried to set the loaded flag manualy like this:

this.newsEntityService.getWithQuery({startIndex: '0', endIndex: '5'}).pipe(
          tap(news => this.newsEntityService.setLoaded(true))
        );

but this isn't working.

I also searched in the documentation and saw that you can override the default reducer, but I dont really have a clue, how this is done.

https://ngrx.io/guide/data/entity-reducer#entity-cache-metareducers

2

There are 2 best solutions below

0
On BEST ANSWER

I had the same problems and it drove me crazy for 2 days, I am not sure if this is the best solution but as a workaround I did this.

return this.paymentsService.loaded$
      .pipe(
        tap(loaded => {
          if (!loaded) {
            this.paymentsService.getWithQuery(this.propertyId.toString()).subscribe(
              {
                next: value => this.paymentsService.setLoaded(true)
              }
            );
          }
        }),
        filter(loaded => !!loaded),
        first()
      );

I subscribed and then set the flag to true and it worked. Now the call to the backend it's made only one time and then the data is getting retrieved from the store.

I hope it helped.

0
On

Use switchMap and hook a pipe to getWithQuery:

return this.paymentsService.loaded$.pipe(
  switchMap(loaded => loaded
    ? of(true)
    : this.paymentsService
      .getWithQuery(this.propertyId.toString())
      .pipe(map(() => true)),
  ),
  first(),
);