What causes the unexpected behavior of MatPaginator within an ngIf statement?

CHECK OUT MY STACKBLITZ DEMO

Here's the material table setup I'm working with:

<table mat-table [dataSource]="dataSource" >
    ... Rows ...
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>  
<mat-paginator #MatPaginator [pageSizeOptions]="[4]" showFirstLastButtons></mat-paginator>

I want to hide the table when the variable info is false.


  1. Strategy 1:
<table *ngIf="info" mat-table [dataSource]="dataSource" >

This approach works, but pagination malfunctions when all rows are displayed on one page.


  1. Strategy 2:
<table [hidden]="!info" mat-table [dataSource]="dataSource" >

Although this makes pagination work, the table still appears empty when info is false.


  1. Strategy 3:

I attempted wrapping the entire table in a div and using *ngIf, but encountered the same issue as Strategy 1.

Even trying [hidden] on the div didn't solve the problem.


  1. UPDATE: Strategy 4:

By directly applying the CSS style="display:none" to the enclosing div, I faced the same dilemma as in Strategy 3 - the table shows up even without data.


Any suggestions on how to properly hide the table when info is false while ensuring functional pagination?

Appreciate any insights!

Answer №1

Here is a recommended approach

 [hidden]="true"

<div [hidden]="true" >
  <table mat-table [dataSource]="dataSource" >
      <ng-container matColumnDef="test">
        <th mat-header-cell *matHeaderCellDef> Test. </th>
          <td mat-cell *matCellDef="let exp"> {{exp}} </td>
      </ng-container>
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  </table>  
  <mat-paginator #MatPaginator [pageSizeOptions]="[2, 4, 6]" showFirstLastButtons> 
  </mat-paginator>
<div>

Explore the demo on StackBlitz

Remember to adjust your condition in [hidden]

Answer №2

To dynamically add a class and use it to hide a table, you can utilize ngClass as shown below:

[ngClass]="{'hidden': !info}"

Add the following CSS rules in your style.css file:

.hidden{
display:none;
}

Check out this demo for a working example.

Answer №3

Placing the paginator within a ngIf is not recommended because it may lead to

this.dataSource.paginator = this.paginator
resulting in this.paginator being undefined. While there is a workaround available if you absolutely must use ngIf (let me know if it's essential), I suggest opting for hidden instead.

Answer №4

Here is a solution using Angular 8:

[hidden] can replace *ngIf, and tab activation can be achieved through CSS properties.

 .tableClass .mat-tab-group.mat-primary .mat-ink-bar {
          width: 160px !important;
        }
<div [hidden]="true" class="tableClass">
     <mat-tab-group>
        <mat-tab label="Tab1">
        </mat-tab>
        <mat-tab label="Tab2">
        </mat-tab>
     </mat-tab-group>
</div>

Answer №5

When faced with a similar issue, I encountered difficulties implementing pagination while using *ngIf and async pipe in my template. However, after conducting some research, I found a solution that involved utilizing the @ViewChild annotation and creating a set function. I have shared my comprehensive solution below to assist others facing the same challenge.

I found that the suggested 'hidden' solution from other replies did not resolve my problem.

Within my component.ts file:

constructor(private cdRef: ChangeDetectorRef) { }

  private paginator: MatPaginator;
  /*
   Using @ViewChild due to ngIf with async pipe on the template 
   Upon emitting data for the first time from the observable, it is necessary to connect the
   pagination component with the datasource. This can be achieved as shown below.
  */
  @ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
    if(mp) {
      this.paginator = mp;
      this.dataSource = new MatTableDataSource<any>(your_data);
      this.dataSource.paginator = this.paginator;
      this.cdRef.detectChanges();
     }
   }

and within my template file:

// incorporating the async pipe with my observable
  <div *ngIf="raceList$ | async as races">
    <div class="mat-table-width">
      <table mat-table [dataSource]="dataSource">
      ...
      </table>
      <mat-paginator [pageSizeOptions]="[10, 20, 30]"
                      showFirstLastButtons
                      aria-label="select page of races">
      </mat-paginator>
    </div>
  </div>

By implementing this approach, I successfully resolved the pagination issue and effectively displayed the table data.

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

What could be causing the dropdown menu to not display below its container when the overflow:hidden CSS property is applied to the container element

One issue I'm facing is that the dropdown submenu of my navigation menu does not extend beyond its container element when displayed. My code includes main menu items (HOME, ABOUT, SERVICES, PRODUCTS, and CONTACT) along with submenu items (A, B, C, D, ...

Is it possible to include jQuery's selectors contain and closest within my CSS selector?

I created a script to hide specific table rows as follows: $('.ms-formtable nobr:contains("Question")').closest('tr').hide(); However, I'm unsure if there is a way to achieve the same result using only CSS. Can anyone provide adv ...

Executing a function within JSX to dismiss a modal in NextJS

I am currently utilizing the Tanstack React Query library to perform a POST request from a Modal that includes a form: const addDay = (day: TDay) => { const apiURL = process.env.NEXT_PUBLIC_SERVER_URL const queryURL = apiURL + router ...

Ways to bypass browser pop-up blockers when using the window.open function

I am displaying an HTML retrieved from the backend. printHtml(htmlContent) { var windowToPrint = window.open('', '_blank'); windowToPrint.document.write(htmlContent); setTimeout(function () { windowToPrint.document ...

Utilize Regular Expression Constant Validator in Angular 8's Reactive Formbuilder for efficient data validation requirements

Is there a way to efficiently store and reuse a Regex Validator pattern in Angular while following the DRY principle? I have a reactive formbuilder with a Regex validator pattern for ZipCode that I need to apply to multiple address forms. I'm interes ...

What is the best way to transfer a value from a parent component to a directive within Angular 2?

In the parent component, I currently have this line of code: <input datepicker type="text" (change)="update($event)"/> Is there a way for me to provide a value to the datepicker directive? ...

Implementation of a function in Typescript that can be defined with a

I am currently diving into the Typescript specification and I'm facing a challenge in creating a functional implementation for describable functions. https://www.typescriptlang.org/docs/handbook/2/functions.html The provided example lacks completene ...

What is the best way to calculate the total sum of dynamically changing inputs in Angular 2?

Is there a way to calculate the total sum from dynamic inputs in angular 2? I'm not sure how to implement this. Thanks! https://i.sstatic.net/eXBjN.png //html component <md-input-container style="width: 80px;"> <input md-inp ...

Shifting between classes in jQuery only takes effect after scrolling occurs

There seems to be an issue with the transition effect in my jQuery code that changes the background color of the .navbar upon scrolling. Even though it is supposed to start with a transparent background, it always begins with a yellow background. I have fo ...

Having trouble loading extensive amounts of data into a select element within an Angular application

Upon successfully retrieving around 14000 data entries from an HTTP request, I am facing difficulties loading this vast amount of data into my Select Tag. This is causing the entire page to slow down. The structure of the select Tag in question is as follo ...

What is the process for specifying a specific font family in CSS?

Despite setting my text to font-family: Times New Roman, I'm seeing a different font in my Chrome browser. Here is the relevant HTML code: <p style="color:#F17141;font-size: 120px; font-family: &quot;Times New Roman&quot; ; font-weight: b ...

Adjust CKEditor's height within Vue.js

I recently began experimenting with integrating ckeditor5 into a Vue.js project. However, I encountered an issue where I couldn't manually adjust its height. Below is the code snippet I used - could you please review it and let me know if there are an ...

Issue with Angular 2 Teamcity Error

Hey team, I'm encountering an error in TeamCity and could use some assistance. [05:40:13][Step 1/6] Update assembly versions: Scanning checkout directory for assembly information related files to update version to 12 [05:40:13][Step 1/6] scan: Search ...

Tips on utilizing a local file as a background image URL

How can I modify my CSS to link to a local file path like C:\xampp\htdocs\Folder instead of the URL https://source.unsplash.com/1600x1050/?nature. I am currently using Bootstrap 4 and below is my CSS code: .jumbotron{ background: ...

Ensuring the completion of all validations in Angular 4

Currently, I'm working on a project that involves 3 FormControls. I am in need of a validation process that ensures either all three have values selected or none at all. Is there a method to achieve this type of validation? ...

Managing Multiple Operations in Angular Firestore

For the past few weeks, I've been grappling with the theory behind this issue. Despite scouring the internet for solutions, I haven't found anything truly helpful. So, I'm turning to the SO community for the first time. In my Firestore data ...

Unable to view newly added components

I am currently in the process of setting up a website, focusing on arranging and formatting everything on the page before moving on to styling and adding JavaScript. I recently added three div tags after my form to create three separate columns in the ne ...

Integrating a neighborhood library with an Angular 5 Project

I want to have a local library that can reflect changes in the project using it. I have cloned the library from this link on my local machine: https://github.com/manfredsteyer/angular-oauth2-oidc Currently, I am navigating to the library directory and run ...

Can you explain the functionality of the statement a:bc = 9 in JavaScript?

Currently in my JavaScript code, I have the equation a:bc = 9. Upon executing `console.log(bc)`, it correctly shows 9. However, if I try to `console.log(a)`, I receive an error stating that "a" is not defined. Can someone provide clarification on what i ...

How can the button press, release, drag, and drop events be implemented in Ionic?

I have been working on adding a recording feature that allows for recording when a button is pressed and stops when it is released. I decided to use the ionic-long-press plugin for this functionality. However, I have noticed that it does not support drag ...