Angular does not support the functionality of having multiple material paginations within a single component

I am currently working on creating a component that contains two dataTables, each with a different dataSource. However, I am facing an issue where my Tables are not visible immediately after the component is loaded due to the *ngIf directive being used. Because of this, I cannot utilize ngAfterViewInit(). Instead, I found a solution on Github that was suggested by a user:

private paginator: MatPaginator;
private reportingPaginator: MatPaginator;
private sort: MatSort;
private reportingSort: MatSort;

@ViewChild(MatSort) set matSort(ms: MatSort) {
  this.sort = ms;
  this.reportingSort = ms;
  this.setDataSourceAttributes();
}

@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
  this.paginator = mp;
  this.reportingPaginator = mp;
  this.setDataSourceAttributes();
}

setDataSourceAttributes() {

    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;

    this.reportingDataSource.paginator = this.reportingPaginator;
    this.reportingDataSource.sort = this.reportingSort;

}

Despite implementing this solution, I am still encountering issues. The pagination does not work when both paginators are included in the @ViewChild(MatPaginator). However, if I include only one of the paginators:

@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
this.reportingPaginator = mp;
this.setDataSourceAttributes();
}

or

@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
this.paginator = mp;
this.setDataSourceAttributes();
}

the included paginator works correctly! What steps should I take to ensure that both paginators work as intended?

Answer №1

When dealing with multiple MatPaginator and MatSort components on a single page, it is important to use the following code snippet:

@ViewChildren(MatPaginator) paginator = new QueryList<MatPaginator>();
@ViewChildren(MatSort) sort = new QueryList<MatSort>();

This code will provide you with a list of MatSort and MatPaginator components in the order they appear on your page. Below is the complete implementation:

import { Component, OnInit, ViewChild, ViewChildren, AfterViewInit, QueryList } from '@angular/core';
import { MatTableDataSource, MatSort, MatPaginator } from '@angular/material';

export interface AssignmentElement {
  assignmentId: number;
  action: string;
  userName: string;
  roleName: string;
  enabled: string;
  createdOn: string;
  createdBy: string;
  modifiedOn: string;
  modifiedBy: string;
  status: string;
}

// Define ASSIGNMENT_ELEMENT_DATA

export interface RoleElement {
  roleId: number;
  action: string;
  roleName: string;
  roleDescription: string;
  createdOn: string;
  createdBy: string;
  modifiedOn: string;
  modifiedBy: string;
  status: string;
}

// Define ROLE_ELEMENT_DATA

@Component({
  selector: 'app-myqueue',
  templateUrl: './myqueue.component.html',
  styleUrls: ['./myqueue.component.css']
})
export class MyQueueComponent implements OnInit, AfterViewInit {

  dataSource1: MatTableDataSource<AssignmentElement>;
  dataSource2: MatTableDataSource<RoleElement>;
  @ViewChildren(MatPaginator) paginator = new QueryList<MatPaginator>();
  @ViewChildren(MatSort) sort = new QueryList<MatSort>();

  assignmentColumn: string[] = [
    // Columns for AssignmentElement
  ];
  roleColumn: string[] = [
    // Columns for RoleElement
  ];

  constructor() {
    this.dataSource1 = new MatTableDataSource<AssignmentElement>(ASSIGNMENT_ELEMENT_DATA);
    this.dataSource2 = new MatTableDataSource<RoleElement>(ROLE_ELEMENT_DATA);
  }

  ngOnInit() {
  }

  ngAfterViewInit() {
    this.dataSource1.paginator = this.paginator.toArray()[0];
    this.dataSource1.sort = this.sort.toArray()[0];
    this.dataSource2.paginator = this.paginator.toArray()[1];
    this.dataSource2.sort = this.sort.toArray()[1];
  }

}

Answer №2

You can also retrieve them using #id:

In the HTML code:

<mat-paginator #categoryPaginator [pageSizeOptions]="[15]" hidePageSize="true" showFirstLastButtons="false"></mat-paginator>

In the component TypeScript file:

@ViewChild('categoryPaginator', { read: MatPaginator }) categoryPaginator: MatPaginator;

UPDATE

Upon further investigation after a comment from gh0st, it appears that the "read" option should be a boolean according to the Angular documentation for ViewChild. I experimented and found that { read: true } does not work, but { read: false } does. However, since false is the default value, omitting it altogether still functions correctly. Therefore, the most concise way to achieve this is:

@ViewChild('categoryPaginator') categoryPaginator: MatPaginator;

I have tested this with three tables/paginators in a single view component and they continue to function as expected.

I speculate that { read: MatPaginator } may actually be interpreted as { read: false }

The Angular documentation provides a basic example of this:

A template reference variable as a string (e.g., query <my-component #cmp></my-component> with @ViewChild('cmp'))

UPDATE-2

In a particular scenario where I had two Material Autocomplete components within one module and required access to the MatAutocomplete trigger for one of them, it seems that specifying { read: MatAutocompleteTrigger } is crucial. Otherwise, it will only return an ElementRef:

@ViewChild('localityAutoComplete', { read: MatAutocompleteTrigger }) trigger: MatAutocompleteTrigger;

Answer №3

It's important to exercise caution when utilizing ViewChild alongside an ngIf directive that evaluates to false, as the ViewChild won't grab any values in this scenario.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Narrowing Down State Types

I am working on a functional component in NextJS with props passed from SSR. The component has a state inside it structured like this: const MyComponent = ({err, n}: {err?: ErrorType, n?: N})=>{ const [x, setX] = useState(n || null) ... if(e ...

Seeking a guide on how to effectively utilize Angular 6 for consuming REST API and performing CRUD operations

I am a beginner with Angular and I am currently using Version 6, specifically the CLI tool. My main focus right now is learning how to make REST API calls. I have searched for tutorials on this topic but unfortunately, none of them have been successful fo ...

Need to import Vue component TWICE

My question is simple: why do I need to import the components twice in the code below for it to function properly? In my current restricted environment, I am unable to utilize Webpack, .vue Single File Components, or npm. Despite these limitations, I mana ...

Discovering the process of reaching service members through an HTML View

Currently, I am in the process of learning Angular 2 and find myself unsure about the most efficient way to update the view. For instance, let's say I have two components: User and Main. The User component retrieves a list of users from the UserServ ...

Utilizing Angular 10 to Transform a JSON Data into a Custom String for HTML Rendering

I have received a JSON response from my backend built using Spring Boot. The "category" field in the response can either be 1 or 2, where 1 represents Notifications and 2 represents FAQs. { "pageNumber": 0, "size": 5, "totalPages&q ...

Display an error popup if a server issue occurs

I'm considering implementing an Error modal to be displayed in case of a server error upon submitting a panel. I'm contemplating whether the appropriate approach would be within the catch statement? The basic code snippet I currently have is: u ...

Using ngFor in Angular 6 to create a table with rowspan functionality

Check out this functional code snippet Desire for the table layout: <table class="table table-bordered "> <thead> <tr id="first"> <th id="table-header"> <font color="white">No.</font> </th> <th id="table-hea ...

Seasonal selection tool

I need a quarterly date picker feature, ideally using Angular. I am interested in something similar to the example shown below: https://i.stack.imgur.com/9i0Cl.png It appears that neither Bootstrap nor (Angular) Material have this capability. Are there a ...

Present information in a tabular format upon identifying an individual's ID using Angular

I encountered a specific issue recently. I successfully connected an API to my database using Angular, and it functions well by displaying all the data in a table. However, when I try to retrieve data for a single ID, the result can only be seen in an inpu ...

The ERR_ASSERTION error is thrown because the catch clause variable is not an instance of the Error class

For some reason, I am unable to set up the authentication, firestore, and cloud storage in my project as I keep getting this error message: [error] AssertionError [ERR_ASSERTION]: catch clause variable is not an Error instance at assertIsError (C:\Us ...

PrimeNG Component Containing a Dynamic Dialog Instance

I am experiencing an issue with handling dynamic dialogs in PrimeNG. Is there a solution for managing actions on a dialog other than just using the close option? For instance, in the context of the Kendo-UI dialog example, I can specify the content.insta ...

An issue has occurred: Angular2 is reporting that Observable_1.Observable.defer is not recognized as a

Recently, I made the transition of my Angular app from version 4 to 6. Here is a peek at my package details: Package.json file: { "version": "0.10.50", "license": "MIT", "angular-cli": {}, ... Upon running npm run start, an error popped up in th ...

Hide Decimal Places with Angular Pipe

I am working with a progress bar that can have a progress ranging from 0.1 to 99.999 In the TypeScript file, I prefer not to use the math.round function as it will disrupt the logic. My intention is to display the progress without decimal points, for exam ...

Can you help me identify any issues with this code for uploading an image and quickly displaying it in Angular?

Located within the profile.component.html file <label for="profile">Profile Photo</label> <input type="file" [(ngModel)]='uploadedPhoto'/> <img [src]='uploadedPhoto'> Contained in the profile.component.ts file ...

Encountering a 404 error while attempting to utilize ng2-charts

I am encountering an issue while attempting to integrate ng2-charts. Despite going through numerous similar threads on GitHub and other platforms, I have yet to find a solution. The error message I am receiving is as follows: Error: (SystemJS) XHR error ( ...

Utilize only the necessary components from firebase-admin in Cloud Functions with Typescript

When I looked at my transpiled code from cloud functions, I noticed the following TypeScript import: import { auth, firestore } from 'firebase-admin'; It gets transpiled to: const firebase_admin_1 = require("firebase-admin"); Upon further exa ...

Avoiding Maximum Call Stack Size Exceeded in Observables: Tips and Tricks

After filtering, I have a list stored in the variable filteredEvents$: public filteredEvents$ = new BehaviorSubject([]); I also have a method that toggles the checked_export property and updates the list: public checkAll(): void { this.filteredEve ...

I am attempting to incorporate an NPM package as a plugin in my Next.js application in order to prevent the occurrence of a "Module not found: Can't resolve 'child_process'" error

While I have developed nuxt apps in the past, I am new to next.js apps. In my current next.js project, I am encountering difficulties with implementing 'google-auth-library' within a component. Below is the code snippet for the troublesome compon ...

Refreshing the Mat Dialog content when removing items in Angular Material

I have successfully implemented a mat dialog table with 3 columns - name, email, and delete icon. When the user clicks on the delete icon, it prompts a confirmation message to confirm the deletion. Upon confirming, the item is removed from the database. Ho ...

Effortlessly sending information to the Material UI 'Table' element within a ReactJS application

I have integrated a materialUI built-in component to display data on my website. While the code closely resembles examples from the MaterialUI API site, I have customized it for my specific use case with five labeled columns. You can view my code below: h ...