Sorry but I'm in the dark with this one.
I have a method that returns an array of objects and I use that array of objects to display a table. this is the function that I'm using:
getCompetitions(): Promise<Competition[]> {
let options: RequestOptionsArgs = {};
let params = new URLSearchParams();
params.append('size', '250');
options.params = params;
return this.http.get(this.competitionsUrl,options)
.toPromise()
.then(response => response.json()._embedded.competitions as Competition[])
.catch(this.handleError);
}
My ngOnInit() method was calling that function on start and getting an array of competitions which was iterated with ngFor and I was creating the table without a problem.
What I want is to implement md-table or cdk-table component. I have the rest of the app using that UI library.
I add my files below, I know the problem is in the implementation or how I'm trying to populate the dataSource.
Here is the competition class:
export class Competition {
compName: string;
compStart: Date;
compEnd: Date;
compFull: number;
compTeamCount: number;
compChamp: number;
compRunnerup: number;
compType: number;
compCountry: string;
_links: {
self: {
href: string;
},
matches: {
href: string;
}
}
}
Here is the Component
import { Component, OnInit } from '@angular/core';
import { DataSource } from '@angular/cdk';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Competition } from '../../competition/competition';
import { CompetitionService } from '../../competition/competition.service'
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
@Component({
selector: 'comp-table-cmp',
moduleId: module.id,
templateUrl: 'competitions-table.component.html',
})
export class CompetitionsTableComponent{
//1- Define my columns
displayedColumns = ['compName'];
//2- Define the database as a new database
competitionsDatabase = new CompetitionsDatabase();
//3- Define the datasource
competitionsDatasource: CompetitionsDatasource | null;
ngOnInit() {
//4 - declare the datasource.
this.competitionsDatasource = new CompetitionsDatasource(this.competitionsDatabase);
console.log(this.competitionsDatasource);
}
}
export class CompetitionsDatabase {
competitions: Competition[];
dataChange: BehaviorSubject<Competition[]> = new BehaviorSubject<Competition[]>([]);
get data(): Competition[] {
this.competitions = [];
this.competitionService.getCompetitions().then(
results => {
results.forEach(result => {
if (result.compType === 1) {
this.competitions.push(result);
this.dataChange.next(results);
}
//Call Method to retrieve team names.
});
return results;
}
)
console.log(this.dataChange);
return this.competitions;
}
constructor(
private competitionService: CompetitionService,
) {}
}
export class CompetitionsDatasource extends DataSource<any> {
constructor(private _exampleDatabase: CompetitionsDatabase) {
super();
}
/** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable<Competition[]> {
console.log('ExampleDataSource#connect')
return this._exampleDatabase.dataChange;
}
disconnect() {}
}
And the HTML:
<div class="example-container mat-elevation-z8">
<cdk-table #table [dataSource]="CompetitionsDatasource" class="example-table">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- CompName Column -->
<ng-container cdkColumnDef="compName">
<cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> CompName </cdk-header-cell>
<cdk-cell *cdkCellDef="let row" class="example-cell"> {{competition.compName}} </cdk-cell>
</ng-container>
<cdk-header-row *cdkHeaderRowDef="displayedColumns" class="example-header-row"></cdk-header-row>
<cdk-row *cdkRowDef="let row; columns: displayedColumns;" class="example-row"></cdk-row>
</cdk-table>
</div>
The result is just the header "CompName"
Please help!
The DataSource is meant to serve a place to encapsulate any sorting, filtering, pagination, and data retrieval logic specific to the application. So, a datasource therefore contains all logic required for sorting, filtering and paginating data.
The CdkTable is an unopinionated, customizable data-table with a fully-templated API, dynamic columns, and an accessible DOM structure. This component acts as the core upon which anyone can build their own tailored data-table experience.
MatTableDataSource. Data source that accepts a client-side data array and includes native support of filtering, sorting (using MatSort), and pagination (using MatPaginator). Allows for sort customization by overriding sortingDataAccessor, which defines how data properties are accessed.
You can't define let row
and then do data binding to {{competition.compName}}
. You need to switch the declaration to let competition
OR do the data binding with row
.
Either:
<cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.compName}} </cdk-cell>
Or:
<cdk-cell *cdkCellDef="let competition" class="example-cell"> {{competition.compName}} </cdk-cell>
Also, you can do the data retrieval and connect()
by extending DataSource
class only. Here's a Plunker example of simplified version of your table.
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