diff --git a/src/material-experimental/mdc-paginator/paginator.spec.ts b/src/material-experimental/mdc-paginator/paginator.spec.ts index 73287748b1f0..d952ce363df1 100644 --- a/src/material-experimental/mdc-paginator/paginator.spec.ts +++ b/src/material-experimental/mdc-paginator/paginator.spec.ts @@ -511,6 +511,31 @@ describe('MDC-based MatPaginator', () => { const hostElement = fixture.nativeElement.querySelector('mat-paginator'); expect(hostElement.getAttribute('role')).toBe('group'); }); + + it('should update the page index when switching to a smaller length', fakeAsync(() => { + const fixture = createComponent(MatPaginatorApp); + const instance = fixture.componentInstance; + instance.length = 50; + instance.pageSize = 10; + instance.pageIndex = 4; + fixture.detectChanges(); + + expect(instance.paginator.pageIndex).toBe(4); + + instance.pageEvent.calls.reset(); + + instance.length = 10; + fixture.detectChanges(); + tick(); + + expect(instance.paginator.pageIndex).toBe(0); + expect(instance.pageEvent).toHaveBeenCalledWith( + jasmine.objectContaining({ + previousPageIndex: 4, + pageIndex: 0, + }), + ); + })); }); function getPreviousButton(fixture: ComponentFixture) { diff --git a/src/material/paginator/paginator.spec.ts b/src/material/paginator/paginator.spec.ts index 84bdb4e64b68..c0c4a0ad8522 100644 --- a/src/material/paginator/paginator.spec.ts +++ b/src/material/paginator/paginator.spec.ts @@ -506,6 +506,31 @@ describe('MatPaginator', () => { const hostElement = fixture.nativeElement.querySelector('mat-paginator'); expect(hostElement.getAttribute('role')).toBe('group'); }); + + it('should update the page index when switching to a smaller length', fakeAsync(() => { + const fixture = createComponent(MatPaginatorApp); + const instance = fixture.componentInstance; + instance.length = 50; + instance.pageSize = 10; + instance.pageIndex = 4; + fixture.detectChanges(); + + expect(instance.paginator.pageIndex).toBe(4); + + instance.pageEvent.calls.reset(); + + instance.length = 10; + fixture.detectChanges(); + tick(); + + expect(instance.paginator.pageIndex).toBe(0); + expect(instance.pageEvent).toHaveBeenCalledWith( + jasmine.objectContaining({ + previousPageIndex: 4, + pageIndex: 0, + }), + ); + })); }); function getPreviousButton(fixture: ComponentFixture) { diff --git a/src/material/paginator/paginator.ts b/src/material/paginator/paginator.ts index da80f713d1dc..f363277e9fcc 100644 --- a/src/material/paginator/paginator.ts +++ b/src/material/paginator/paginator.ts @@ -129,6 +129,18 @@ export abstract class _MatPaginatorBase< } set length(value: number) { this._length = coerceNumberProperty(value); + + const maxPageIndex = Math.max(this.getNumberOfPages() - 1, 0); + const currentPageIndex = this._pageIndex; + + if (currentPageIndex > maxPageIndex && this.initialized) { + // Needs to happen on the next tick, in order to avoid "changed after checked" errors. + Promise.resolve().then(() => { + this._pageIndex = maxPageIndex; + this._emitPageEvent(currentPageIndex); + }); + } + this._changeDetectorRef.markForCheck(); } private _length = 0;