How to translate MatPaginator
© https://angular.io/

How to translate MatPaginator

Translate Angular`s MatPaginator (Material Design Components)

ByMario Kandut

honey pot logo

Europe’s developer-focused job platform

Let companies apply to you

Developer-focused, salary and tech stack upfront.

Just one profile, no job applications!

When building an Angular application often the Material Design Components from Angular are used. Many use cases require the application to be translated. There are plenty of different translation modules available. When you have tables with paginators in your application, it's getting a bit more complicated than just changing a string.

MatPaginator or <mat-paginator> provides navigation for paged information, typically used with a table.

💰 The Pragmatic Programmer: journey to mastery. 💰 One of the best books in software development, sold over 200,000 times.

Each paginator instance requires:

  • The number of items per page (default set to 50)
  • The total number of items being paged
  • The current page index defaults to 0, but can be explicitly set via pageIndex.

The paginator displays a dropdown of page sizes for the user to choose from. The options for this dropdown can be set.

One translation only

Angular provides the MatPaginatorIntl so you can internationalize the labels, though if you only want to translate into one language, you can do it likes this:

this.paginator._intl.itemsPerPageLabel = 'Items pro Seite';
this.paginator._intl.nextPageLabel = 'Nächste';
this.paginator._intl.previousPageLabel = 'Vorherige';

The future-proof way would be to provide an own instance of MatPaginatorIntl.

Internationalization

The labels for the paginator can be customized by providing your own instance of MatPaginatorIntl.

This will allow you to change the following:

  • The label for the length of each page.
  • The range text displayed to the user.
  • The tooltip messages on the navigation buttons.

Let's walk through an example with using ngx-translate.

1. Create Injectable Class

The class subscribes to language changes, also unsubscribes onDestroy, and updates the translations accordingly, for more details visit Github - Angular Issue/Feature.

import { Injectable, OnDestroy } from '@angular/core';
import { MatPaginatorIntl } from '@angular/material';
import { TranslateService } from '@ngx-translate/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class CustomMatPaginatorIntl extends MatPaginatorIntl
  implements OnDestroy {
  unsubscribe: Subject<void> = new Subject<void>();
  OF_LABEL = 'of';

  constructor(private translate: TranslateService) {
    super();

    this.translate.onLangChange
      .takeUntil(this.unsubscribe)
      .subscribe(() => {
        this.getAndInitTranslations();
      });

    this.getAndInitTranslations();
  }

  ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete();
  }

  getAndInitTranslations() {
    this.translate
      .get([
        'PAGINATOR.ITEMS_PER_PAGE',
        'PAGINATOR.NEXT_PAGE',
        'PAGINATOR.PREVIOUS_PAGE',
        'PAGINATOR.OF_LABEL',
      ])
      .takeUntil(this.unsubscribe)
      .subscribe(translation => {
        this.itemsPerPageLabel =
          translation['PAGINATOR.ITEMS_PER_PAGE'];
        this.nextPageLabel = translation['PAGINATOR.NEXT_PAGE'];
        this.previousPageLabel =
          translation['PAGINATOR.PREVIOUS_PAGE'];
        this.OF_LABEL = translation['PAGINATOR.OF_LABEL'];
        this.changes.next();
      });
  }

  getRangeLabel = (
    page: number,
    pageSize: number,
    length: number,
  ) => {
    if (length === 0 || pageSize === 0) {
      return `0 ${this.OF_LABEL} ${length}`;
    }
    length = Math.max(length, 0);
    const startIndex = page * pageSize;
    const endIndex =
      startIndex < length
        ? Math.min(startIndex + pageSize, length)
        : startIndex + pageSize;
    return `${startIndex + 1} - ${endIndex} ${
      this.OF_LABEL
    } ${length}`;
  };
}

2. Import & Update provider

Import and add the class in providers in your app.module.tsfile.

import { CustomMatPaginatorIntl } from './shared/custom-mat-paginator-intl';
providers: [
  {
    provide: MatPaginatorIntl,
    useClass: CustomMatPaginatorIntl,
  },
];

3. Done

🎉🎉🎉 Congratulations! 🎉🎉🎉

You have successfully internationalized MatPaginator.

TL;DR

Material Design Components from Angular make a lot of things easier, unfortunately translating the paginator is not one of them. To provide a translation you have to:

  • Create an injectable class, which listens to language changes and updates translations
  • Provide translation in app.module

Thanks for reading and if you have any questions, use the comment function or send me a message @mariokandut. If you want to know more about Angular, have a look at these Angular Tutorials.

References (and Big thanks): Google - Angular, Konrad Klimczak, Github - Angular Issue/Feature

Scroll to top ↑