2017-09-27 6 views
0

Ich versuche, Daten einfach aus einer MySQL-Datenbank mit Angular (5) mit einer Materialtabelle anzuzeigen. Der Code, den ich erfolgreich kompiliert habe, und eine Tabelle mit den Spaltennamen und Paginierungsschaltflächen wird angezeigt, aber in der Tabelle werden keine Daten angezeigt. Ich weiß, dass der API-Aufruf Daten korrekt zurückgibt, und ich weiß, dass der Dienst die API aufruft (ich kann die korrekten Daten im Netzwerkinspektor im Browser sehen). Es ist ein Fehler im BrowserAngular 5 Materialtabelle, die keine Daten vom Dienst erhält

gezeigt
TypeError: _co.unitTypeDatabase.data is undefined 
Stack trace: 
View_UnitTypeComponent_0/<@ng:///AppModule/UnitTypeComponent.ngfactory.js:136:9 ... 

Es erscheinen würde, dass der Fehler in den HTML-Code auf den Teil bezieht sich unter Bezugnahme auf unitTypeDatabase.data.length. Wenn das nicht definiert ist, würde es erklären, warum auch keine Daten in der Tabelle vorhanden sind. Was ich nicht herausfinden kann, ist warum das ist undefined. Ich denke, es hat damit zu tun, wie/wann/wo ich die new UnitTypeDatabase erstelle, aber da der Dienst erfolgreich aufgerufen wird, bin ich nicht sicher, wohin ich von hier aus gehen soll. Hier ist der Code, ich habe:

einheits type.component.ts

import { Component, OnInit, ViewChild } from '@angular/core'; 
import { UnitType } from './unit-type'; 
import { UnitTypeService } from './unit-type.service'; 
import {DataSource} from '@angular/cdk/collections'; 
import {MdPaginator} from '@angular/material'; 
import {Observable} from 'rxjs/Observable'; 
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; 

@Component({ 
    selector: 'app-unit-type', 
    templateUrl: './unit-type.component.html', 
    styleUrls: ['./unit-type.component.scss'], 
    providers: [UnitTypeService] 
}) 
export class UnitTypeComponent implements OnInit { 
    public displayedColumns = ['unitTypeID', 'unitTypeName']; 
    public unitTypeDatabase: UnitTypeDatabase | null; 
    public dataSource: UnitTypeDataSource | null; 

    @ViewChild(MdPaginator) paginator: MdPaginator; 

    constructor(private unitTypeService: UnitTypeService) {} 

    ngOnInit() { 
     this.unitTypeDatabase = new UnitTypeDatabase(this.unitTypeService); 
     this.dataSource = new UnitTypeDataSource(this.unitTypeDatabase, this.paginator); 
    } 
} 

export class UnitTypeDataSource extends DataSource<UnitType> { 
    constructor(private _unitTypeDatabase: UnitTypeDatabase, private _paginator: MdPaginator) { 
     super(); 
    } 

    connect(): Observable<UnitType[]> { 
    const displayDataChanges = [ 
     this._unitTypeDatabase.dataChange, 
     this._paginator.page 
    ]; 

    return Observable.merge(...displayDataChanges).map(() => { 
     const data = this._unitTypeDatabase.data.slice(); 

     const startIndex = this._paginator.pageIndex * this._paginator.pageSize; 
     return data.splice(startIndex, this._paginator.pageSize); 
    }) 
    } 

    disconnect() {} 
} 

export class UnitTypeDatabase { 
    /** Stream that emits whenever the data has been modified. */ 
    public dataChange: BehaviorSubject<UnitType[]> = new BehaviorSubject<UnitType[]>([]); 
    get data(): UnitType[] { return this.dataChange.value; } 

    constructor(unitTypeService: UnitTypeService) { 
     unitTypeService.getAllUnitTypes().subscribe(data => this.dataChange.next(data)); 
    } 
} 

einheits type.component.html

<div class="example-container mat-elevation-z8"> 
    <md-table #table [dataSource]="dataSource"> 

    <!-- ID Column --> 
    <ng-container mdColumnDef="unitTypeID"> 
     <md-header-cell *mdHeaderCellDef> ID </md-header-cell> 
     <md-cell *mdCellDef="let row"> {{row.unitTypeID}} </md-cell> 
    </ng-container> 

    <!-- Name Column --> 
    <ng-container mdColumnDef="unitTypeName"> 
     <md-header-cell *mdHeaderCellDef> Name </md-header-cell> 
     <md-cell *mdCellDef="let row"> {{row.unitTypeName}} </md-cell> 
    </ng-container> 

    <md-header-row *mdHeaderRowDef="displayedColumns"></md-header-row> 
    <md-row *mdRowDef="let row; columns: displayedColumns;"></md-row> 
    </md-table> 

    <md-paginator #paginator 
      [length]="unitTypeDatabase.data.length" 
      [pageIndex]="0" 
      [pageSize]="25" 
      [pageSizeOptions]="[5, 10, 25, 100]"> 
    </md-paginator> 
</div> 

einheits type.ts

export class UnitType { 
    constructor(
     public unitTypeID: number, 
     public unitTypeName: string 
    ){} 
} 

einheits type.service.ts

import { Injectable } from '@angular/core'; 
import { UnitType } from './unit-type'; 
import { Headers, Http } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 

@Injectable() 
export class UnitTypeService { 
    private unit_types_Url = 'api/unit-types'; // URL to web api 
    private headers = new Headers({'Content-Type': 'application/json'}); 

    constructor(private http: Http) { } 

    getAllUnitTypes(): Observable<UnitType[]> { 
    return this.http.get(this.unit_types_Url) 
      .map(response => response.json().data as UnitType[]); 
    } 
} 

ich mit dem Beispiel aus dem Material-Website gestartet, aber diese Daten nicht abrufen einen Dienst. Ich habe auch versucht, die Frage und Antwort von How to use md-table with services in Angular 4 übereinstimmen, aber ich muss etwas verpassen. Hoffentlich ist es ein offensichtlicher und einfacher Fehler oder ein Missverständnis, das jemand schnell erkennen kann. Vielen Dank!

bearbeiten Der vollständige Stack-Trace ist:

ERROR TypeError: _this._unitTypeDatabase.data is undefined 
Stack trace: 
[208]/UnitTypeDataSource.prototype.connect/<@http://localhost:4200/main.bundle.js:93:17 
[email protected]://localhost:4200/vendor.bundle.js:51417:22 
[email protected]://localhost:4200/vendor.bundle.js:37214:13 
[email protected]://localhost:4200/vendor.bundle.js:48573:9 
[email protected]://localhost:4200/vendor.bundle.js:117362:9 
[email protected]://localhost:4200/vendor.bundle.js:37214:13 
[email protected]://localhost:4200/vendor.bundle.js:26457:17 
[email protected]://localhost:4200/vendor.bundle.js:49978:9 
UnitTypeDatabase/<@http://localhost:4200/main.bundle.js:122:78 
[email protected]://localhost:4200/vendor.bundle.js:37363:13 
[email protected]://localhost:4200/vendor.bundle.js:37310:17 
[email protected]://localhost:4200/vendor.bundle.js:37250:9 
[email protected]://localhost:4200/vendor.bundle.js:37214:13 
[email protected]://localhost:4200/vendor.bundle.js:51423:9 
[email protected]://localhost:4200/vendor.bundle.js:37214:13 
[email protected]://localhost:4200/vendor.bundle.js:53409:21 
[email protected]://localhost:4200/polyfills.bundle.js:6443:17 
[email protected]://localhost:4200/vendor.bundle.js:4914:24 
[email protected]://localhost:4200/polyfills.bundle.js:6442:17 
[email protected]://localhost:4200/polyfills.bundle.js:6242:28 
ZoneTask/[email protected]://localhost:4200/polyfills.bundle.js:6496:28 

enter image description here

Antwort

0

Das Problem ist in der Einheit-type.service.ts. Es sollte sein:

getAllUnitTypes(): Observable<UnitType[]> { 
    return this.http.get(this.unit_types_Url) 
      .map(response => response.json() as UnitType[]); 
} 

ich die Tatsache übersehen, dass es als Teil der zurückgegebenen JSON, so bald kein Datenobjekt war, das entfernt wurde alle Informationen sichtbar war und korrekt in der Tabelle angezeigt.

1

versuchen, einen elvis Operator ? in der Vorlage zu verwenden, um mit zu beginnen. Wenn es nur das Template-Problem ist, sollte das Ihr Problem lösen.

[length]="unitTypeDatabase?.data?.length" 

Der Grund dafür ist, wenn die Ansicht gerendert wird es keine unitTypeDatabase noch definiert ist, wie es nur in den ngOnInit() initialisiert wird. Sehen Sie, ob das Ihr Problem behebt.

+0

Danke für den Tipp, aber leider hat das das Problem nicht gelöst. Ich bekomme immer noch den gleichen Fehler im Browser wie zuvor. – Tim

+0

können Sie die vollständige Stack-Ablaufverfolgung des Fehlers anzeigen? – amal

+0

Ich habe die Frage bearbeitet, um den vollständigen Stack-Trace anzuzeigen. – Tim