Angular 5中MatTableDataSource报错:'OrderDataSource'无'subscribe'属性
Property 'subscribe' does not exist on type 'OrderDataSource'错误 Hey there, let's break down why you're hitting this error and how to fix it quickly!
The root issue here is that your custom OrderDataSource (which extends DataSource from @angular/cdk/collections) isn't an Observable itself — it's a wrapper that exposes an Observable via its connect() method. When you try to call subscribe() directly on the OrderDataSource instance, TypeScript rightfully complains because that method doesn't exist on the class.
Here's how to fix this, depending on your use case:
1. Fix your custom OrderDataSource implementation
First, make sure your data source properly implements the DataSource interface. It needs two methods: connect() (which returns the Observable of your data) and disconnect() (for cleanup). Here's a standard example:
import { DataSource } from '@angular/cdk/collections'; import { Observable } from 'rxjs'; import { OrderService } from '../services/order.service'; export class OrderDataSource extends DataSource<any> { constructor(private orderService: OrderService) { super(); } // This returns the actual data Observable MatTable will subscribe to connect(): Observable<Order[]> { return this.orderService.fetchOrders(); // Replace with your data fetch logic } // Clean up any subscriptions if needed disconnect() { // Add cleanup code here (e.g., unsubscribe from long-lived observables) } }
2. Use the data source correctly in your component
You have two options here, depending on whether you need manual access to the data:
Option A: Let MatTable handle the subscription (recommended)
You don't need to call subscribe() at all — just assign your OrderDataSource instance to the MatTable's dataSource property, and the table will automatically call connect() and subscribe to the data stream:
// In your order.component.ts import { Component, OnInit } from '@angular/core'; import { OrderDataSource } from './order-data-source'; import { OrderService } from '../services/order.service'; @Component({ selector: 'app-order', templateUrl: './order.component.html' }) export class OrderComponent implements OnInit { dataSource: OrderDataSource; constructor(private orderService: OrderService) {} ngOnInit() { this.dataSource = new OrderDataSource(this.orderService); } }
Then in your template:
<table mat-table [dataSource]="dataSource"> <!-- Your column definitions here --> </table>
Option B: Manually subscribe to the data stream
If you need to process the data before it reaches the table, subscribe to the Observable returned by connect() instead of the data source itself:
// In your component's ngOnInit or another lifecycle hook this.dataSource.connect().subscribe(orders => { // Do something with the orders data (e.g., filter, transform) console.log('Fetched orders:', orders); });
3. Simplify with MatTableDataSource (if you don't need custom logic)
If you aren't doing complex data handling (like server-side pagination/sorting), skip the custom DataSource entirely and use MatTableDataSource directly. It's built for simpler use cases and works seamlessly with arrays or Observables:
import { MatTableDataSource } from '@angular/material/table'; import { Observable } from 'rxjs'; // In your component dataSource: MatTableDataSource<Order>; ngOnInit() { // Option 1: If you have a static array // this.dataSource = new MatTableDataSource(yourStaticOrderArray); // Option 2: If you're fetching data from a service this.orderService.fetchOrders().subscribe(orders => { this.dataSource = new MatTableDataSource(orders); }); }
This approach avoids the custom data source boilerplate and eliminates the subscribe() error entirely, since you're either working with a plain array or subscribing to the service's Observable directly.
内容的提问来源于stack exchange,提问作者Ashutosh

