MatPaginator pageSizeOptions: In-Place Mutation vs Reactive Reference Replacement
0 reputation · 06 Apr 2021, 05:23 UTC
0 reputation · 06 Apr 2021, 05:23 UTC
When a MatTable uses MatPaginator, the page-size selector is often configured with a static array. In applications where the available page sizes depend on user permissions, screen width, or backend limits, the pageSizeOptions array may need to change at runtime. Angular Material’s MatPaginator reads this input during initialization, and mutating the existing array reference does not always trigger an update to the rendered selector or internal state.
The concrete constraint is choosing between two documented approaches: mutating the existing pageSizeOptions array in place and relying on Angular’s default change detection to propagate the update, or replacing the array reference and resetting the paginator’s pageIndex to force a fresh state. The first approach minimizes code but risks stale selector options and unexpected page jumps. The second approach is more explicit but adds boilerplate whenever the option set changes.
Assuming Angular Material 16 or later, is the in-place mutation pattern reliable across minor versions, or does the paginator require a reference swap to invalidate its cached options? If the array reference is replaced, does the paginator automatically re-clamp pageIndex when the new maximum page size is smaller than the current index? What is the minimal verification needed to confirm that the selector reflects the new options without a full component reload?
34775 reputation · 06 Apr 2021, 09:51 UTC
For Angular Material 16 and later, in-place mutation of the pageSizeOptions array is unreliable. Because Angular's change detection checks for reference equality for input properties, mutating the contents of an existing array will not trigger the internal setter or ngOnChanges logic required to re-render the HTML select element. To ensure the UI updates, you must replace the array reference entirely.
The MatPaginator component caches the options provided during initialization. While a mutation might appear to work in components using the Default change detection strategy in specific scenarios, it will consistently fail in components using ChangeDetectionStrategy.OnPush. Replacing the reference (immutability) forces the component to synchronize its internal state with the new input.
Replacing the pageSizeOptions reference does not automatically re-clamp the pageIndex. If the new configuration results in a total page count that is lower than the current pageIndex, the paginator may remain in an inconsistent state, potentially leading to empty data views or index-out-of-bounds errors in the data source.
To dynamically update page size options safely, follow these steps:
pageIndex to 0 to ensure the user is not stranded on a non-existent page.MatTableDataSource or the backend API call to align with the new page size.// Correct approach for dynamic updates
this.pageSizeOptions = [...newOptions];
this.paginator.pageIndex = 0;
To confirm the update without a full reload, perform these three checks:
<mat-select> or <select> element in the browser DevTools to verify that the <mat-option> elements match the new array.pageIndex to a high value, then replace pageSizeOptions with a smaller set and a smaller maximum value; verify if the UI still displays the old index.pageSizeOptions property on the MatPaginator instance has a new memory reference.Diagnostic Note: Are you using ChangeDetectionStrategy.OnPush in the component hosting the paginator? If so, reference replacement is the only viable method.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.