-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Table] simpler example without example database #6036
Comments
I agree with @willshowell about the md-table example being too complex https://material.angular.io/guide/cdk-table. For example, I am using the HTTPModule to access my data from an api. I have a JSON res coming back, and I would like to simply add this res to the And thank you to the angular-material team for making really amazing stuff for us to use. import { Component } from '@angular/core';
import { DataSource } from '@angular/cdk';
import { MdSort } from '@angular/material';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { Http, Response, RequestOptions, Headers, Request, RequestMethod } from '@angular/http';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
export interface Data {}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
myData: Array < any > ;
displayedColumns = ['id', 'name'];
dataSource: MyDataSource;
constructor(private http: Http) {
this.getData();
}
public getData() {
let url = 'https://api.mydatafeeds.com/v1.1/cumulative_player_data.json?';
let headers = new Headers({ "Authorization": "123ykiki456789123456" });
let options = new RequestOptions({ headers: headers });
this.http.get(url, options)
.map(response => response.json())
.subscribe(res => {
this.myData = res;
this.dataSource = new MyDataSource(this.myData);
});
}
}
export class MyDataSource extends DataSource<any> {
constructor(private data: Data[]) {
super();
}
/** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable<Data[]> {
return Observable.of(this.data);
}
disconnect() {}
} Edit: I made some changes based on the simple code example above. Now my <md-table #table [dataSource]="dataSource">
<ng-container cdkColumnDef="id">
<md-header-cell *cdkHeaderCellDef> Id </md-header-cell>
<md-cell *cdkCellDef="let data"> <b>{{data.person.id}}.</b>
</md-cell>
</ng-container>
<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
<md-row *cdkRowDef="let data; columns: displayedColumns;"></md-row>
</md-table> This doesn't work. <div *ngFor="let data of myData">
{{data.person.id}}
</div> edit: Nevermind. It works now! I can render my json response in the md-table. |
Maybe an explanation similar to this could accompany the example,
|
Just connecting to an external db such as Firebase for the example data would be a very good thing for us newbies! Also, why does the Plunker basic data table example import every MD module? This doesn't seem necessary. |
I'm missing an example connecting to an external DB and doing things like Sorting, Filtering, etc on server-side. Is it possible with MdTable? |
@mitidiero Here's how to connect to a client side service in Angular 4 and Firebase. I'm trying to figure out filtering now. |
The @iposton example got me over the hump on this. Just changed 'md-' to 'mat-' and 'cdkxxx' to 'matxxx' and off to the races. Thanks much. |
Another simplified generc data source:
usage:
in template
also, you can add a constructor to SimpleDatasource and init data with it. |
Anyway it would be possible to design a table completely in HTML. Without data source binding. Like: <mat-table>
<mat-header-row>
<mat-header-cell>One</mat-header-cell>
<mat-header-cell>Two</mat-header-cell>
<mat-header-cell>Three</mat-header-cell>
</mat-header-row>
<mat-row>
<mat-cell>Foo</mat-cell>
<mat-cell>Bar</mat-cell>
<mat-cell>Haha</mat-cell>
</mat-row>
</mat-table> Or conventionally: <table>
<thead>
<tr>
<th>One</th>
<th>Two</th>
<th>Three</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of items;">
<td>{{item.one}}</td>
<td>{{item.two}}</td>
<td>{{item.three}}</td>
</tr>
</tbody>
</table> |
Can anybody help in using filter and pagination after getting data from the server |
@utk23dubey take a look at this article: https://material.angular.io/components/table/overview |
@KEMBL thanks for the help.But i have gone thru it already.:) |
I originally set up my example above using the paginator table. I had it working, but didn't like how it reset my index when I clicked a new page. I didn't save it, but I think this is how I made it work. I have not tested this in a while so it might not be what you are looking for, but maybe it can help :) import { Component, ViewChild } from '@angular/core';
import { DataSource } from '@angular/cdk';
import { MatPaginator } from '@angular/material';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { Http, Response, RequestOptions, Headers, Request, RequestMethod } from '@angular/http';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
export interface Data {}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
myData: Array < any > ;
displayedColumns = ['id', 'name'];
dataSource: MyDataSource;
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor(private http: Http) {
this.getData();
}
public getData() {
let url = 'https://api.mydatafeeds.com/v1.1/cumulative_player_data.json?';
let headers = new Headers({ "Authorization": "123ykiki456789123456" });
let options = new RequestOptions({ headers: headers });
this.http.get(url, options)
.map(response => response.json())
.subscribe(res => {
this.myData = res;
this.dataSource = new MyDataSource(this.myData, this.paginator);
});
}
}
export class MyDataSource extends DataSource<any> {
constructor(private dataBase: Data[], private paginator: MatPaginator) {
super();
}
/** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable<Data[]> {
//return Observable.of(this.dataBase);
const displayDataChanges = [
//Observable.of(this.dataBase),
this.dataBase.dataChange,
this.paginator.page,
];
return Observable.merge(...displayDataChanges).map(() => {
const data = this.dataBase.slice();
// //console.log(data, 'merge');
// // Grab the page's slice of data.
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
const finalData = data.splice(startIndex, this.paginator.pageSize);
// console.log(finalData, 'finalData')
return finalData;
});
}
disconnect() {}
} <md-table #table [dataSource]="dataSource">
<ng-container cdkColumnDef="id">
<md-header-cell *cdkHeaderCellDef> Id </md-header-cell>
<md-cell *cdkCellDef="let data"> <b>{{data.person.id}}.</b>
</md-cell>
</ng-container>
<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
<md-row *cdkRowDef="let data; columns: displayedColumns;"></md-row>
<mat-paginator #paginator
[length]="myData.data.length"
[pageIndex]="0"
[pageSize]="25"
[pageSizeOptions]="[5, 10, 25, 100]">
</mat-paginator>
</md-table> Update: Wow I was missing quite a few important lines to make this work. I forgot to inject the
|
create a material looking table (withOUT dataTable) #3805 |
Having errors while using sort and filter the table:(.None of the examples are helping me out |
@utk23dubey sorry to hear this. I tried to use sort and paginator together and I think it was no bueno. I could be wrong but I think you can only use one angular material2 feature for the data table. But if you can post your code or the error messages I can try to help you with your project. |
@iposton After so much of hours spend.Finally my code works.Your Example helped me a lot:). |
@utk23dubey can you post final code. |
@nikhilb1208 just see the above code which is posted and do changes according to your need.My code is just the revised version of this code only. |
1 similar comment
@nikhilb1208 just see the above code which is posted and do changes according to your need.My code is just the revised version of this code only. |
For me the above code is not working. Sometimes I have the feeling that the name Angular came from anger, that is my feeling as a noob when I try to learn something new. Why is it so hard to provide a little peace of running code on the official website that gives a starting point to develop further. Breaking changes in the naming of tags and in the import sources are real nails for my coffin |
@aracis42 it's worth noting that most of the conversation in this thread occurred while Material was in beta and was initially focused on making the documentation better. Github issues typically aren't the best place to expect evergreen code, far less so for a library that is actively evolving around user feedback. There are loads of people on StackOverflow that are happy to help troubleshoot issues with you, and would probably be happy to do here as well! But simply saying the code (which code?) is not working (how is it not working?) in your unique context isn't going to get you to an answer. |
The code above from iposton above is not working because even the tags like are deprecated in newer versions. The description in https://material.angular.io/components/table/overview#sorting is IMHO not really helpful. Never mind, I give up with material tables and switch over to ag-grid. |
This Example Has Been Updated to comply with Angular 5 and latest material2 release. April 12, 2018 @aracis42 I feel your pain. I have added a sample using import { Component, ViewChild, Inject, OnInit, ElementRef } from '@angular/core';
import { MatTableDataSource, MatSort } from '@angular/material';
import { DataSource } from '@angular/cdk/table';
import { Observable } from 'rxjs/Observable';
import { HttpClient, HttpResponse, HttpHeaders, HttpRequest} from '@angular/common/http';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
export interface Data {}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
myData: Array < any > ;
displayedColumns = ['id', 'name'];
dataSource: MyDataSource;
@ViewChild(MatSort) sort: MatSort;
constructor(private http: HttpClient) {}
getData() {
let url = 'https://api.mydatafeeds.com/v1.1/cumulative_player_data.json?';
let headers = new HttpHeaders({ "Authorization": "123ykiki456789123456" });
this.http.get(url, {headers})
.subscribe(res => {
this.myData = res;
this.dataSource = new MyDataSource(this.myData, this.sort);
});
}
ngOnInit() {
this.getData();
}
}
export class MyDataSource extends DataSource < any > {
constructor(private dataBase: Data[], private sort: MatSort) {
super();
}
/** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable < Data[] > {
const displayDataChanges = [
Observable.of(this.dataBase),
this.sort.sortChange,
];
return Observable.merge(...displayDataChanges).map(() => {
return this.getSortedData();
});
}
disconnect() {}
/** Returns a sorted copy of the database data. */
getSortedData(): Data[] {
const data = this.dataBase.slice();
if (!this.sort.active || this.sort.direction == '') { return data; }
return data.sort((a, b) => {
let propertyA: number | string = '';
let propertyB: number | string = '';
switch (this.sort.active) {
case 'id':
[propertyA, propertyB] = [a.id, b.id];
break;
case 'name':
[propertyA, propertyB] = [a.name, b.name];
break;
}
let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
let valueB = isNaN(+propertyB) ? propertyB : +propertyB;
return (valueA < valueB ? -1 : 1) * (this.sort.direction == 'asc' ? 1 : -1);
});
}
} <mat-table #table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header> Id </mat-header-cell>
<mat-cell *matCellDef="let data"> <b>{{data.id}}.</b>
</mat-cell>
</ng-container>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header> Id </mat-header-cell>
<mat-cell *matCellDef="let data"> <b>{{data.name}}.</b>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let data; columns: displayedColumns;"></mat-row>
</mat-table> Update: I added the new HttpClient to this example. And I am using the old sort example from an older version of angular-material. The latest example uses |
@iposton can you also provide me the same example for filtering the mat table. Thanks so much..!! |
This Example Has Been Updated to comply with Angular 5 and latest material2 release. April 12, 2018 @deepali-kakkar this sounds fun. Let me try to get it working in my app and if I do I will post the code here. import { Component, ViewChild, Inject, OnInit, ElementRef } from '@angular/core';
import { MatTableDataSource, MatSort } from '@angular/material';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { DataSource } from '@angular/cdk/table';
import { Observable } from 'rxjs/Observable';
import { HttpClient, HttpResponse, HttpHeaders, HttpRequest} from '@angular/common/http';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/observable/fromEvent';
export interface Data {}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
myData: Array < any > ;
displayedColumns = ['id', 'name'];
dataSource: MyDataSource;
@ViewChild('filter') filter: ElementRef;
constructor(private http: HttpClient) {}
public getData() {
let url = 'https://api.mydatafeeds.com/v1.1/cumulative_player_data.json?';
let headers = new HttpHeaders({ "Authorization": "123ykiki456789123456" });
this.http.get(url, {headers})
.subscribe(res => {
this.myData = res;
this.dataSource = new MyDataSource(this.myData);
});
}
ngOnInit() {
this.getData();
Observable.fromEvent(this.filter.nativeElement, 'keyup')
.debounceTime(150)
.distinctUntilChanged()
.subscribe(() => {
if (!this.dataSource) { return; }
this.dataSource.filter = this.filter.nativeElement.value;
});
}
export class MyDataSource extends DataSource < any > {
_filterChange = new BehaviorSubject('');
get filter(): string { return this._filterChange.value; }
set filter(filter: string) { this._filterChange.next(filter); }
constructor(private dataBase: Data[]) {
super();
}
/** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable < Data[] > {
const displayDataChanges = [
this._filterChange
];
return Observable.merge(...displayDataChanges).map(() => {
return this.dataBase.slice().filter((item: Data) => {
let searchStr = (item.name).toLowerCase();
return searchStr.indexOf(this.filter.toLowerCase()) != -1;
});
});
}
disconnect() {}
} <div class="example-header">
<input matInput #filter placeholder="Filter by name">
</div>
<mat-table #table [dataSource]="dataSource">
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef> Id </mat-header-cell>
<mat-cell *matCellDef="let data"> <b>{{data.id}}.</b>
</mat-cell>
</ng-container>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef> Id </mat-header-cell>
<mat-cell *matCellDef="let data"> <b>{{data.name}}.</b>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let data; columns: displayedColumns;"></mat-row>
</mat-table> @deepali-kakkar Update: I tested this and it worked with a json response from an api. The big difference from my other examples is using I added these imports from the
I want to point out that you will need to include ps the original example on angular-material's website used |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Bug, feature request, or proposal:
Docs request
Motivation
#5917 (comment)
Also, many of the table-related questions posted here and on stack overflow show that folks don't really understand the purpose and use of ExampleDatabase. They are trying to copy/paste/mold it to fit their solution, when it really is just a support class for the example.
Proposed Example
I think first-time readers would greatly benefit from seeing a single-emission data source without any frills. Then, once they want to know how to make their table more interesting and dynamic, they can learn about the benefits of Subjects, DAOs, etc in the more complicated examples with a better understanding of how the foundation works.
The text was updated successfully, but these errors were encountered: