Skip to content

Commit 339c2eb

Browse files
committed
fix(material/paginator): update page index if invalid after length change
Updates the page index of a paginator if its length changed to something where the index isn't valid anymore (e.g. the user is on the last page and the amount of pages becomes smaller). Fixes #14520.
1 parent 603b248 commit 339c2eb

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

src/material-experimental/mdc-paginator/paginator.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,31 @@ describe('MDC-based MatPaginator', () => {
511511
const hostElement = fixture.nativeElement.querySelector('mat-paginator');
512512
expect(hostElement.getAttribute('role')).toBe('group');
513513
});
514+
515+
it('should update the page index when switching to a smaller length', fakeAsync(() => {
516+
const fixture = createComponent(MatPaginatorApp);
517+
const instance = fixture.componentInstance;
518+
instance.length = 50;
519+
instance.pageSize = 10;
520+
instance.pageIndex = 4;
521+
fixture.detectChanges();
522+
523+
expect(instance.paginator.pageIndex).toBe(4);
524+
525+
instance.pageEvent.calls.reset();
526+
527+
instance.length = 10;
528+
fixture.detectChanges();
529+
tick();
530+
531+
expect(instance.paginator.pageIndex).toBe(0);
532+
expect(instance.pageEvent).toHaveBeenCalledWith(
533+
jasmine.objectContaining({
534+
previousPageIndex: 4,
535+
pageIndex: 0,
536+
}),
537+
);
538+
}));
514539
});
515540

516541
function getPreviousButton(fixture: ComponentFixture<any>) {

src/material/paginator/paginator.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,31 @@ describe('MatPaginator', () => {
506506
const hostElement = fixture.nativeElement.querySelector('mat-paginator');
507507
expect(hostElement.getAttribute('role')).toBe('group');
508508
});
509+
510+
it('should update the page index when switching to a smaller length', fakeAsync(() => {
511+
const fixture = createComponent(MatPaginatorApp);
512+
const instance = fixture.componentInstance;
513+
instance.length = 50;
514+
instance.pageSize = 10;
515+
instance.pageIndex = 4;
516+
fixture.detectChanges();
517+
518+
expect(instance.paginator.pageIndex).toBe(4);
519+
520+
instance.pageEvent.calls.reset();
521+
522+
instance.length = 10;
523+
fixture.detectChanges();
524+
tick();
525+
526+
expect(instance.paginator.pageIndex).toBe(0);
527+
expect(instance.pageEvent).toHaveBeenCalledWith(
528+
jasmine.objectContaining({
529+
previousPageIndex: 4,
530+
pageIndex: 0,
531+
}),
532+
);
533+
}));
509534
});
510535

511536
function getPreviousButton(fixture: ComponentFixture<any>) {

src/material/paginator/paginator.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ export abstract class _MatPaginatorBase<
129129
}
130130
set length(value: number) {
131131
this._length = coerceNumberProperty(value);
132+
133+
const maxPageIndex = Math.max(this.getNumberOfPages() - 1, 0);
134+
const currentPageIndex = this._pageIndex;
135+
136+
if (currentPageIndex > maxPageIndex && this.initialized) {
137+
// Needs to happen on the next tick, in order to avoid "changed after checked" errors.
138+
Promise.resolve().then(() => {
139+
this._pageIndex = maxPageIndex;
140+
this._emitPageEvent(currentPageIndex);
141+
});
142+
}
143+
132144
this._changeDetectorRef.markForCheck();
133145
}
134146
private _length = 0;

0 commit comments

Comments
 (0)