title: Angular Material DataTable databinding
body: <p>I'm using <a href="https://material.angular.io/" rel="nofollow noreferrer">Angular Material</a> and attempting to get the DataTable working with an Http response object. I have the DataSource setup and the table rows are being populated but none of the content is being display in the table. I get a blank row entry for each object in the collection but I can see the data using Augury to inspect the table properties.</p>
  
  <p>Here is the component:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
  import { DataSource } from '@angular/cdk';
  import { ResponseSearchResult } from './response-search-result';
  import { SearchService } from '../shared/search.service';
  import { Observable } from 'rxjs/Observable';
  import { BehaviorSubject } from 'rxjs/BehaviorSubject';
  import 'rxjs/add/operator/map';
  import 'rxjs/add/observable/of';
  import 'rxjs/add/observable/merge';
  
  
  @Component({
    selector: 'search-results',
    templateUrl: './results.component.html',
    styleUrls: ['./results.component.scss']
  })
  
  export class ResultsComponent implements OnInit {
    displayedColumns: ["ResponseConditionName", "ResponseText", "RelatedLinks"];
    searchTerm: string;
    templateItems: number[];
    loadingData: boolean;
    searchResults: any = null;
    dataSource: SearchDataSource | null;
  
    constructor(private searchService: SearchService, private changeDetector: ChangeDetectorRef) {
    }
  
    ngOnInit() {
  
      this.dataSource = new SearchDataSource(this.searchService);
  
      this.searchService.loadingSearchResults.subscribe({
        next: (value) =&gt; this.loadingData = value
      });
    }
  }
  
  export class SearchDataSource extends DataSource&lt;any&gt; {
    constructor(private searchService: SearchService) {
      super();
    }
  
    subject = new BehaviorSubject&lt;ResponseSearchResult[]&gt;([]);
  
    connect(): Observable&lt;ResponseSearchResult[]&gt; {
  
      this.searchService.searchResults.subscribe({
        next: (value) =&gt; {
          this.subject.next(value);
        }
      });
      return Observable.merge(this.subject);
    }
  
    disconnect() {
      this.subject.complete();
      this.subject.observers = [];
    }
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div *ngIf="dataSource"&gt;
    &lt;md-table #searchResultsTable [dataSource]="dataSource"&gt;
      &lt;ng-container cdkColumnDef="ResponseConditionName"&gt;
        &lt;md-header-cell *cdkHeaderCellDef&gt; Name &lt;/md-header-cell&gt;
        &lt;md-cell *cdkCellDef="let row"&gt; {{row.ResponseConditionName}} &lt;/md-cell&gt;
      &lt;/ng-container&gt;
                  
      &lt;ng-container cdkColumnDef="ResponseText"&gt;
        &lt;md-header-cell *cdkHeaderCellDef&gt; Response &lt;/md-header-cell&gt;
        &lt;md-cell *cdkCellDef="let row"&gt; {{row.ResponseText}} &lt;/md-cell&gt;
      &lt;/ng-container&gt;
    
      &lt;ng-container cdkColumnDef="RelatedLinks"&gt;
        &lt;md-header-cell *cdkHeaderCellDef&gt; RelatedLinks &lt;/md-header-cell&gt;
        &lt;md-cell *cdkCellDef="let row"&gt;
          &lt;a *ngFor="let link of row.RelatedLinks"&gt;
            {{link.LinkName}}
          &lt;/a&gt;
        &lt;/md-cell&gt;
      &lt;/ng-container&gt;
  
      &lt;md-header-row *cdkHeaderRowDef="displayedColumns"&gt;&lt;/md-header-row&gt;
      &lt;md-row *cdkRowDef="let row; columns: displayedColumns;"&gt;&lt;/md-row&gt;
    &lt;/md-table&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Here is the data object being returned by the service:</p>
  
  <pre><code>export class ResponseSearchResult {
    UnitName: string;
    ResponseConditionName: string;
    ResponseText: string;
    RelatedLinks: RelatedLink[];
    NavigationUrl: NavigationUrl;
    Owner: string;
    WorkflowStatus: string;
  }
  </code></pre>
  
  <p>And here is the service itself:</p>
  
  <pre><code>import { Injectable } from '@angular/core';
  import { HttpClient } from '@angular/common/http';
  import { BehaviorSubject } from 'rxjs/BehaviorSubject';
  import { SearchQuery } from '../search/search-query';
  import { ResponseSearchResult } from '../results/response-search-result';
  
  @Injectable()
  export class SearchService {
  
    public searchResults: BehaviorSubject&lt;ResponseSearchResult[]&gt; = new BehaviorSubject&lt;ResponseSearchResult[]&gt;(null);
    public loadingSearchResults: BehaviorSubject&lt;boolean&gt; = new BehaviorSubject&lt;boolean&gt;(null);
  
    constructor(private http: HttpClient) {}
  
    submitResponseSearch(searchQuery: SearchQuery) {
      this.loadingSearchResults.next(true);
      let searchTypes = this.getSelectedSearchTypes(searchQuery);
  
      this.http.get&lt;ResponseSearchResult[]&gt;(
        `/api/search/GetSearchResults?searchString=${searchQuery.searchTerm}&amp;searchTypes=${searchTypes}`).subscribe(response =&gt; {
  
        this.searchResults.next(response);
        this.loadingSearchResults.next(false);
      });
    }
  
    getSelectedSearchTypes(searchQuery: SearchQuery) {
      return searchQuery.searchTypes.filter(type =&gt; type.IsSelected).map(({ Name }) =&gt; Name).join(",");
    }
  
  
  }
  </code></pre>
  
  <p>Here is a screencap of the console output from the service return in SearchDataSource:</p>
  
  <p><a href="https://i.stack.imgur.com/4qZ9h.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4qZ9h.png" alt="enter image description here"></a></p>