i'am working on a assignment of angular 4, i'am new to it, i'am applying pagination for mat-table,getting some problem in it, while i'am printing data to console it is displaying as below
while i'am trying to apply dataSource.data.length, getting below error.
WellComponent.html:57 ERROR TypeError: Cannot read property 'length' of undefined
at Object.View_WellComponent_0._co [as updateDirectives] (WellComponent.html:60)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13075)
at checkAndUpdateView (core.es5.js:12255)
at callViewAction (core.es5.js:12620)
at execComponentViewsAction (core.es5.js:12552)
at checkAndUpdateView (core.es5.js:12261)
at callViewAction (core.es5.js:12620)
at execEmbeddedViewsAction (core.es5.js:12578)
at checkAndUpdateView (core.es5.js:12256)
at callViewAction (core.es5.js:12620)
Can i get help in this aspect, how should i access that length property.
Component:
import { MatPaginator } from '@angular/material';
import { DataSource } from '@angular/cdk/collections';
import { Component, OnInit,ViewChild,ChangeDetectorRef } from '@angular/core';
import { WellService } from '../services/well.service';
import { Well } from '../well/well';
import { Observable } from 'rxjs/Rx';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
@Component({
selector: 'app-well',
templateUrl: './well.component.html',
styleUrls: ['./well.component.css'],
providers:[WellService]
})
export class WellComponent implements OnInit {
title = 'Wells';
header:string;
displayedColumns = ['active', 'company', 'country', 'well','wellbore'];
public dataSource: WellDataSource | any;
obs:any;
@ViewChild(MatPaginator) paginator : MatPaginator;
constructor(private wellService:WellService) {
this.header='assets/images/BHI_header_logo_bd.png'
}
ngOnInit() {
this.obs = this.wellService.getWells();
this.dataSource = new WellDataSource(this.obs, this.paginator);
}
}
export class WellDataSource extends DataSource<any> {
constructor(private _obs: any, private _paginator: MatPaginator) {
super();
}
connect(): Observable<any[]> {
const displayDataChanges = [
this._obs,
this._paginator.page,
];
return this._obs.flatMap(x => {
return Observable.merge(...displayDataChanges).map(() => {
const data = x.slice();
console.log(data);
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
console.log(startIndex);
console.log(this._paginator.pageSize)
console.log(this._obs);
console.log(x.slice());
return data.splice(startIndex, this._paginator.pageSize);
});
})
}
disconnect() {}
}
**HTML:**
<div>
<div class="image"><img [src]="header" ></div>
<div class="w3-display-left">
<nav>
<li><a routerLink="/wells" routerLinkActive="active">My Wells</a></li>
<li><a routerLink="/dev" routerLinkActive="active">Well Management</a></li>
<li><a routerLink="/dev" routerLinkActive="active">Admin Tools</a></li>
</nav>
<div class="w3-display-right">
<button mat-button>Reset</button>
<button mat-button>Refresh</button>
<button mat-button>View Wireline</button>
<button mat-button>Chat</button>
<button mat-button>View Seismic</button>
<button mat-button>Alerts</button>
</div>
<br>
<br>
<div>
<mat-table #table [dataSource]="dataSource">
<!-- Active -->
<ng-container matColumnDef="active">
<mat-header-cell *matHeaderCellDef> Active </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.active}} </mat-cell>
</ng-container>
<!-- Company -->
<ng-container matColumnDef="company">
<mat-header-cell *matHeaderCellDef> Company </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.company}} </mat-cell>
</ng-container>
<!-- Country -->
<ng-container matColumnDef="country">
<mat-header-cell *matHeaderCellDef>Country</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.country}} </mat-cell>
</ng-container>
<!-- Well -->
<ng-container matColumnDef="well">
<mat-header-cell *matHeaderCellDef> Well </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.well}} </mat-cell>
</ng-container>
<!-- Wellbore -->
<ng-container matColumnDef="wellbore">
<mat-header-cell *matHeaderCellDef> Wellbore </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.wellbore}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<mat-paginator #paginator
[length]="dataSource.data.length"
[pageIndex]="0"
[pageSize]="25"
[pageSizeOptions]="[5, 10, 25, 100]">
</mat-paginator>
</div>
</div>
<div>
<router-outlet></router-outlet>
</div>
The "Cannot read property 'length' of undefined" error occurs when accessing the length property on an undefined value. To solve the error, make sure to only access the length property on data types that support it - arrays or strings.
What Causes TypeError: Cannot Read Property of Undefined. Undefined means that a variable has been declared but has not been assigned a value. In JavaScript, properties and functions can only belong to objects.
The error is because of you are trying to access data before it available
Try to use safe operator :
dataSource.data?.length
OR
make some initialisation inside constructor
dataSource.data = [];
As per your code change [length]="dataSource.data.length"
to [length]="obs.data?.length"
, like this :
<mat-paginator #paginator
[length]="obs.data?.length"
[pageIndex]="0"
[pageSize]="25"
[pageSizeOptions]="[5, 10, 25, 100]">
</mat-paginator>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With