4


I have a grid that contains heavy data to be loaded and so the loading time became not manageable. The solution I found was do a sequential number of http requests, each one retrieving batches of 100 rows, till fulfill all data on the grid. I know how to implement 2 sequential http requests using concatMap and it works perfectly but I would like to have a while loop that would validate each response and if the current number of rows < total number of rows then subscribe a new Http request. It's strange I don't find any solution for this, maybe I'm thinking wrong from the very beginning this solution :D Any help would be very welcome! Thanks in advance!

Forwarding code used for execute 2 http requests using concatMap:

private LoadGridStringResourcesInProject(projectId: number) {
let allData: StringResource[] = [];
const batchSize = 100;

this.stringResourcesService.getStringResourcesInProject(projectId, 0, batchSize)
    .pipe(
      concatMap(firstData => {
        const stringResourcesInProject = firstData as StringResource[];

        // Loads first 100 rows on the Grid
        this.gridApi.updateRowData({ add: stringResourcesInProject });
        this.agGridService.refreshSizeColumns(this.agGrid);

        // Fetch data returned by partial Http requests
        allData = stringResourcesInProject;

        if (allData && allData.length == batchSize) {

          // Do new Http request to fetch the remaining data
          return this.stringResourcesService
            .getStringResourcesInProject(projectId, batchSize, 0);
        }

        return [];
      })
    ).subscribe(data => {
        const stringResourcesInProject = data as StringResource[];

        // Loads the remaining rows in the Grid
        this.gridApi.updateRowData({ add: stringResourcesInProject });

        // Fetch data returned by partial Http requests
        allData = allData.concat(stringResourcesInProject);
      },
      error => of(null),
      () => {
        this.agGridService.refreshSizeColumns(this.agGrid);
      });

}

2
  • 3
    The operator you're looking for is expand :) Commented Jan 16, 2020 at 11:47
  • Thank you so much @Maxim1992. Working like a charme :) Commented Jan 16, 2020 at 14:49

1 Answer 1

3

Like @Maxim1992 said, the solution is using the Expand RxJS operator in order to call recursively! Thank you so much @Maxim1992!

More information here: Example

Here is the code you can use also (hope it can help someone in the future):

private LoadGridStringResourcesInProject(projectId: number) {
const batchSize = 1000;
let iteraction = 0;


this.stringResourcesService.getStringResourcesInProject(projectId, false, false, false, 0, batchSize)
  .pipe(
    expand(partialData => {
      if (partialData) {
        let partialStringResourcesInProject = partialData as StringResource[];

        if (partialStringResourcesInProject.length > batchSize) {

          // Loads the remaining rows in the Grid
          this.gridApi.updateRowData({ add: partialStringResourcesInProject });

          iteraction += 1;

          return this.stringResourcesService.getStringResourcesInProject(projectId, false, false, false,
                       batchSize * (iteraction - 1), batchSize);
        }

        return EMPTY;
      }
    })
  ).subscribe(data => {

        //... 
  },
  error => of(null),
  () => {
    this.agGridService.refreshSizeColumns(this.agGrid);
  });
Sign up to request clarification or add additional context in comments.

1 Comment

Glad you figured out the solution once you heard of expand :) well done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.