0

I'm very new to ngrx-data and I'm try to detect why loading a few records is taking so long

Here is how I subscribe to the ngrx-data entities:

    this.subscriptions.push(this.mileageTrackingManagmentService.entities$.subscribe(data => {
      console.log('>>subscribe mileageTrackingManagmentService - ' + new Date());
      let tempDataset = data || [];
      this.calculateTotalMileageForMultipleDays(tempDataset);
      this.mileageTrackingManagment = tempDataset;
      this.filteredMileageTrackingManagement = this.mileageTrackingManagment;
      //this.setFilter();
      //this.cdRef.detectChanges();
    }));

Here is how I call the ngrx-data service to make the http request

  private loadMileageTracking() {
    if (this.domain) {
      console.log('loadMileageTracking');
      if (this.dateOption == DateOptions.Day && this.selectedResource) {
        this.mileageTrackingService.getTrackingByResourceIdAndDomainId(this.startDate, this.selectedResource.resourceId, this.domain.id);
      } else {
        console.log('getManagment');
        this.mileageTrackingManagmentService.getManagment(this.startDate, this.endDate, this.dateOption, this.domain.id)
      }
    }
  }

From what I can see in the console, subscribe reaction logic is gettig called twice with 15 seconds difference. In the network tab I can see that both request are sucessful and contain data.

I'm doing wrong the detection change to display the data, is this standard behavior ? enter image description here

Things that I have tried

  • entities$.pipe(skip(1)).subscribe...
  • entities$.pipe(take(1)).subscribe...

None of the work as expected since only the a given request is shown and any other is ignored

I'm not looking at a way to ignore returned data by the request, what I want is to know why ngrx-data or my code is doing two http request for a single call the a ngrx-data service

Here is how the service is implemeneted

export class MileageTrackingManagmentService extends EntityCollectionServiceBase<MileageTrackingManagment> {

    constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
        super('MileageTrackingManagment', serviceElementsFactory);
    }

    public getManagment(startDate: Moment, endDate: Moment, grouping: DateOptions, domainId?: string): Observable<MileageTrackingManagment[]> {
        this.clearCache();

        return this.getWithQuery(MileageCommon.buildQuery(startDate, endDate, grouping, domainId));
    }
}

I have also checked other similar questions without much luck

Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
  • If `entities$` is a `BehaviorSubject` you will always get the initial value on subscribing (first time it runs), then when you update it it'll run again with new data (second time it runs). If you want to skip the initial value use `entities$.pipe(skip(1)).subscribe(...)`. – Jason White Dec 31 '21 at 16:54
  • `entities$ is an `observable` that ngrx-data exposes from the services, using this approach is not working, requests are made but only the 2nd data is shown, after that nothing gests is being shown – Mauricio Gracia Gutierrez Dec 31 '21 at 17:34
  • @JasonWhite Thanks for your comment, I have updated my question to explain better my issue, also showing what your approach is producing as result. – Mauricio Gracia Gutierrez Dec 31 '21 at 17:40
  • mind sharing the definition of `this.mileageTrackingManagmentService.entities$` ? – The Fabio Jan 01 '22 at 02:17
  • @TheFabio entities$ is not defined by me, is on the base service - https://ngrx.io/api/data/EntityCollectionServiceBase : `entities$: Observable | Store` – Mauricio Gracia Gutierrez Jan 01 '22 at 14:39
  • 1
    Thank you. I guess there is always something new to learn in nx... i did not know this EntityCollectionServiceBase class. I will propose an answer with what i think its happening shortly – The Fabio Jan 03 '22 at 10:51

2 Answers2

2

If everything else you do app-wide with the returned data works as expected and you just need the data once in the given page/context, you can try to add a pipe(take(1)) to subscription [with import { take } from 'rxjs/operators';], to be sure you're getting just the first value emitted. See more at https://rxjs.dev/api/operators/take

Misha Mashina
  • 1,739
  • 2
  • 4
  • 10
1

I believe this is what is happening: entities$.subscribe( yields once with entities$ current value, then once more every time entities$'s value changes.

When the subscription takes place (at this line)

 ... (this.mileageTrackingManagmentService.entities$.subscribe(data => ...

The current entities$ value is yield;

Then the call to the service function loadMileageTracking happens.

Then some time passes (15s per your pic) and the FE received the data;

This causes the data to be changed on the store related to your entities, and as a consequence ...entities$.subscribe(data => ... yields again.

if you need the subscription to not yield while Back-End is processing the service's http request, I suggest you add a property to you store to indicate if the values are loading or not.

let me call it loading, and assume you have an observable loading$ for it in you service for the sake of the argument. Then you can do this:

this.mileageTrackingManagmentService.loading$.pipe(filter(loading => !loading),take(1)).subscribe(() => {
{
  this.subscriptions.push(this.mileageTrackingManagmentService.entities$.subscribe(data => {
    let tempDataset = data || [];
    this.calculateTotalMileageForMultipleDays(tempDataset);
    this.mileageTrackingManagment = tempDataset;
    this.filteredMileageTrackingManagement = this.mileageTrackingManagment;
  }));
});

In this example you would also need to add the handling of the loading property value to your reducer. The action sets its value to true and both the success and failure related actions set it to false.

The Fabio
  • 5,369
  • 1
  • 25
  • 55
  • The weird thing is that I see two http requests, one for the first time subscribe is called and then another, the first one is faster and the other takes 15 seconds to get the same data. I have re-installed my local environment and will test your approach, thanks – Mauricio Gracia Gutierrez Jan 03 '22 at 13:16
  • 1
    After deleting the local repo and getting a fresh version of master, this issue is no longer happening, thanks for your help – Mauricio Gracia Gutierrez Jan 03 '22 at 17:27