I've three different div (Post, Todo, User)
, based on user selection I display different table. For example, by default Post
section loads with table of 100 records.
If user selects Todo
section, table should display Todo
records and so on with pagination.
I've three datasource
and three paginators
in angular component. All these table data are fetched using REST GET call. I'm getting all the data but the pagination is not working as expected.
Pagination is working only for the Post
section, remaining two (todo and user)
paginators are not working.
Please find my code below, what I'm doing wrong here - I'm struggling from last two days not able to figure out why pagination is not working for all of them.
It would be really appreciated if you could help me with below issues. Appreciated your help in advance. Thanks!
Post has total 100 records
Todo has total 200 records
User has total 10 records
my-service.component.ts
import { Component, OnInit, ViewChild, ViewChildren, QueryList } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort, Sort } from '@angular/material/sort';
import { MyService } from './my-service';
import { Todo } from './todos';
//import {MatAutocompleteTrigger} from '@angular/material/autocomplete';
@Component({
selector: 'demo-service',
templateUrl: './demo-service.component.html',
styleUrls: ['./demo-service.component.scss'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class DemoServiceComponent implements OnInit {
selectedProject: string = 'Posts';
postDataSource = new MatTableDataSource();
postColumns = ['userId', 'title', 'body'];
@ViewChild('postPaginator') postPaginator: MatPaginator;
todoDataSource = new MatTableDataSource();
toDoColumns = ['userId', 'title', 'completed'];
@ViewChild('todoPaginator') todoPaginator: MatPaginator
userDataSource = new MatTableDataSource();
userColumns = ['id', 'name', 'username', 'email'];
@ViewChild('userPaginator') userPaginator: MatPaginator
ngAfterViewInit() {
this.postDataSource.paginator = this.postPaginator;
this.todoDataSource.paginator = this.todoPaginator;
this.userDataSource.paginator = this.userPaginator;
}
/**
* Constructor
*/
constructor(
private myService: MyService
) { }
loadData() {
this.onGetToDo();
this.onGetPost();
this.onGetUser();
}
onGetToDo(): void {
this.myService.getTodo().subscribe(
(response) => {
this.todoDataSource.data = response;
},
(error: any) => {
},
() => console.log('Done getting all todos')
);
}
onGetPost(): void {
this.myService.getPost().subscribe(
(response) => {
this.postDataSource.data = response;
},
(error: any) => {
console.log('entering into error block')
},
() => console.log('Done getting all posts')
);
}
onGetUser(): void {
this.myService.getUser().subscribe(
(response) => {
this.userDataSource.data = response;
},
(error: any) => {
console.log('entering into error block')
},
() => console.log('Done getting all posts')
);
}
ngOnInit(): void {
this.loadData();
}
filterTodoData($event: any) {
this.todoDataSource.filter = $event.target.value;
}
filterPostData($event: any) {
this.todoDataSource.filter = $event.target.value;
}
/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
trackByFn(index: number, item: any): any {
return item.id || index;
}
}
HTML File
<div >
<div >
<div >
<div >
<div >
<div >
<ng-container *transloco="let t">
<div
>
List Data</div>
</ng-container>
</div>
</div>
</div>
<div
matRipple [matMenuTriggerFor]="projectsMenu">
<div >
<div >
<div >{{selectedProject}}</div>
</div>
<div >
<mat-icon [svgIcon]="'heroicons_solid:chevron-down'"></mat-icon>
</div>
</div>
<mat-menu #projectsMenu="matMenu" [xPosition]="'before'">
<button mat-menu-item (click)="selectedProject='Posts'">Posts
</button>
<button mat-menu-item (click)="selectedProject='Todo'">To Do
</button>
<button mat-menu-item (click)="selectedProject='User'">User
</button>
</mat-menu>
</div>
</div>
</div>
<div *ngIf="selectedProject === 'Posts'">
<div data-ng-init='listAllTopics()'>
<mat-tab-group [animationDuration]="'0'">
<mat-tab label="Posts">
<ng-template matTabContent>
<div >
<div
>
<mat-form-field >
<mat-icon matPrefix [svgIcon]="'heroicons_solid:search'">
</mat-icon>
<input matInput (keyup)="filterPostData($event)" [autocomplete]="'off'"
[placeholder]="'Search'">
</mat-form-field>
<div >
<table mat-table matSort
(matSortChange)="announceSortChange($event)" [dataSource]="postDataSource"
multiTemplateDataRows>
<ng-container matColumnDef="userId">
<th mat-header-cell *matHeaderCellDef mat-sort-header> userId </th>
<td mat-cell *matCellDef="let element"> {{element.userId}} </td>
</ng-container>
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header> title </th>
<td mat-cell *matCellDef="let element"> {{element.title}} </td>
</ng-container>
<ng-container matColumnDef="body">
<th mat-header-cell *matHeaderCellDef mat-sort-header> body </th>
<td mat-cell *matCellDef="let element"> {{element.body}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="postColumns;sticky: true"></tr>
<tr mat-row *matRowDef="let element; columns: postColumns;"
[class.student-expanded-row]="expandedElement === element"
(click)="expandedElement = expandedElement === element ? null : element">
</tr>
</table>
<mat-paginator #postPaginator="matPaginator"
[length]="this.postDataSource?.filteredData?.length" [pageSize]="10"
[pageSizeOptions]="[10, 20, 30, 50]" showFirstLastButtons>
</mat-paginator>
</div>
</div>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</div>
</div>
<div *ngIf="selectedProject === 'Todo'">
<div data-ng-init='listAllTopics()'>
<mat-tab-group [animationDuration]="'0'">
<mat-tab label="Todos">
<ng-template matTabContent>
<div >
<div
>
<mat-form-field >
<mat-icon matPrefix [svgIcon]="'heroicons_solid:search'">
</mat-icon>
<input matInput (keyup)="filterTodoData($event)" [autocomplete]="'off'"
[placeholder]="'Search'">
</mat-form-field>
<div >
<table mat-table matSort
(matSortChange)="announceSortChange($event)" [dataSource]="todoDataSource"
multiTemplateDataRows>
<ng-container matColumnDef="userId">
<th mat-header-cell *matHeaderCellDef mat-sort-header> userId </th>
<td mat-cell *matCellDef="let element"> {{element.userId}} </td>
</ng-container>
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header> title </th>
<td mat-cell *matCellDef="let element"> {{element.title}} </td>
</ng-container>
<ng-container matColumnDef="completed">
<th mat-header-cell *matHeaderCellDef mat-sort-header> completed </th>
<td mat-cell *matCellDef="let element"> {{element.completed}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="toDoColumns;sticky: true"></tr>
<tr mat-row *matRowDef="let element; columns: toDoColumns;"
[class.student-expanded-row]="expandedElement === element"
(click)="expandedElement = expandedElement === element ? null : element">
</tr>
</table>
<mat-paginator #todoPaginator="matPaginator"
[length]="this.todoDataSource?.filteredData?.length" [pageSize]="10"
[pageSizeOptions]="[10, 20, 30, 50]" showFirstLastButtons>
</mat-paginator>
</div>
</div>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</div>
</div>
<div *ngIf="selectedProject === 'User'">
<div data-ng-init='listAllTopics()'>
<mat-tab-group [animationDuration]="'0'">
<mat-tab label="User">
<ng-template matTabContent>
<div >
<div
>
<mat-form-field >
<mat-icon matPrefix [svgIcon]="'heroicons_solid:search'">
</mat-icon>
<input matInput (keyup)="filterPostData($event)" [autocomplete]="'off'"
[placeholder]="'Search'">
</mat-form-field>
<div >
<table mat-table matSort
(matSortChange)="announceSortChange($event)" [dataSource]="userDataSource"
multiTemplateDataRows>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> id </th>
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="username">
<th mat-header-cell *matHeaderCellDef mat-sort-header> username </th>
<td mat-cell *matCellDef="let element"> {{element.username}} </td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef mat-sort-header> email </th>
<td mat-cell *matCellDef="let element"> {{element.email}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="userColumns;sticky: true"></tr>
<tr mat-row *matRowDef="let element; columns: userColumns;"
[class.student-expanded-row]="expandedElement === element"
(click)="expandedElement = expandedElement === element ? null : element">
</tr>
</table>
<mat-paginator #userPaginator="matPaginator"
[length]="this.userDataSource?.filteredData?.length" [pageSize]="5"
[pageSizeOptions]="[5, 10, 30, 50]" showFirstLastButtons>
</mat-paginator>
</div>
</div>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</div>
</div>
</div>
Service class:
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { Todo } from "./todos";
import { Post } from "./post";
import { User } from "./user";
@Injectable({ providedIn: 'root' })
export class MyService {
constructor(private http: HttpClient) { }
getTodo(): Observable<Todo[]> {
return this.http.get<Todo[]>('http://jsonplaceholder.typicode.com/todos');
}
getPost(): Observable<Post[]> {
return this.http.get<Post[]>('http://jsonplaceholder.typicode.com/posts');
}
getUser(): Observable<User[]> {
return this.http.get<User[]>('http://jsonplaceholder.typicode.com/users');
}
}
CodePudding user response:
Because you are using *ngIf
, the rendered template does not have the elements todo
and user
when ngAfterViewInit
is executed.
You can avoid it by modifying *ngif
to [hidden]
and reverse the conditions.
<div [hidden]="selectedProject !== 'Posts'">
<div [hidden]="selectedProject !== 'Todo'">
<div [hidden]="selectedProject !== 'User'">