Complete solution based on ngx-translate and Observable so supports switching languages in the app.
Create subclass of MatPaginatorIntl in which you inject TranslateService. In the constructor translate the paginator labels and listen for language changes to trigger the same. The rangeLabel is translated with interpolation of the startIndex, endIndex and length variables.
import {MatPaginatorIntl} from "@angular/material/paginator";
import {TranslateParser, TranslateService} from "@ngx-translate/core";
import {Injectable, OnDestroy} from "@angular/core";
import {Subject} from "rxjs";
import {takeUntil} from 'rxjs/operators';
/* Sources:
https://medium.com/front-dev/translate-your-matpaginator-with-ngx-translate-and-stay-reactive-4c7b145cae9
https://www.mariokandut.com/how-to-translate-matpaginator-angular/
*/
@Injectable()
export class TranslatedMatPaginator extends MatPaginatorIntl implements OnDestroy {
private unsubscribe: Subject<void> = new Subject<void>();
private translatedRangeLabel: string = '';
constructor(private translateService: TranslateService, private translateParser: TranslateParser) {
super();
this.translateService.onLangChange
.pipe(takeUntil(this.unsubscribe))
.subscribe(() => {
this.getAndInitTranslations();
});
this.getAndInitTranslations();
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
getAndInitTranslations() {
this.translateService.stream([
'paginator.first.page',
'paginator.items.per.page',
'paginator.last.page',
'paginator.next.page',
'paginator.previous.page',
'paginator.range'
])
.pipe(takeUntil(this.unsubscribe))
.subscribe(translation => {
this.firstPageLabel = translation['paginator.first.page'];
this.itemsPerPageLabel = translation['paginator.items.per.page'];
this.lastPageLabel = translation['paginator.last.page'];
this.nextPageLabel = translation['paginator.next.page'];
this.previousPageLabel = translation['paginator.previous.page'];
this.translatedRangeLabel = translation['paginator.range'];
this.changes.next();
});
}
getRangeLabel = (page: number, pageSize: number, length: number) => {
length = Math.max(length, 0);
const startIndex = page * pageSize;
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
let translation = this.translateParser.interpolate(this.translatedRangeLabel, {startIndex, endIndex, length});
if (translation) {
return translation;
}
return this.translatedRangeLabel;
};
}
In your module code add a provider which basically returns an instance of your custom translated subclass whenever a MatPaginatorIntl instance is required.
in app.module.ts or material.module.ts
import {TranslatedMatPaginator} from "./translated-mat-paginator";
...
providers: [
{provide: MatPaginatorIntl, useClass: TranslatedMatPaginator},
]