Search code examples
angularrxjsangular-material

Rxjs from 2 different sources


I have a form that has 3 fields that get put into an API call as query params. When a button is hit the form is submitted and the API is called and data is put into a table. The table is an Angular Material table, this works well but I want to recall the API with data from the paginated table. So my initial thought was to listen to events from the table for changes to the page events but this proved challenging as it emits on page load.

So how I started to structure it was having the button emit onto a subject but it looks like the Angular Pagination for the material table emits right away on page load with the initial values and using combineLatest on the search$ Subject also seems that its emitting something or the pipe is still running and calling the API

So basically what is happening is the API is being called with no form data because the table paginator is firing right away

here is a very basic stackBlitz

happy to have a better approach for this that is more reactive

very basic looking to try to replicate this: https://material.angular.io/components/table/examples#table-http but I need the API to not be called until the form has valid values (checked by the submit button)


Solution

  • Your call is executed due to your startWith operator. You should apply it on pagination to start it with some value like

    combineLatest([this.paginator.page.pipe(startWith({pageIndex: 0, pageSize: 5})), this.search$])
    

    I'd refactor a bit your solution to make it more clean

    To handle pagination it's better to listen for (page) output, then you'll be able to catch only change without initial value. Initial pagination(page number and size) can be set in your property(ies) and passed as inputs to pagination.

    Form validation can be handled natively by form controls validators instead of manual checks.

    Table component can accept plain array of items, no need for datasource object.

    Also you have potential issues with your length. Paginator awaits full length of your collection (e.g. it can be 100 when page size is 5, so then paginator determines that you have 20 pages). So your BE need to return total amount of items that exists in db and items for corresponding page you have requested.

    here is my refactored version of your table filters/pagination handling:

    https://stackblitz.com/edit/stackblitz-starters-sksrlk?file=src%2Fmain%2Fmain.component.ts