Источник данных таблицы Angular Material не отображает данные

Я пытаюсь создать таблицу котировок акций, используя торговый API IEX. Однако у меня возникают проблемы с подключением его к источнику данных. Я могу использовать ngfor и отображать данные, но данные не отображаются при попытке использовать таблицу. Я не знаю, что еще попробовать. Я подумал, что это может быть то, как я получаю данные из API. В классе обслуживания я пытаюсь преобразовать его в массив, чтобы он мог работать с таблицей.

@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
  displayedColumns: string[] = ['symbol'];
  quote:Quote[] = [];
  dataSource = new QuoteDataSource(this.stocksummary);

  constructor(private stocksummary:StocksummaryService) { }

  ngOnInit() {
  //  this.stocksummary.getStocks().subscribe(t => {this.quote = t});
  //  console.log(this.quote);

  }
}

export class QuoteDataSource extends DataSource<any> {
  constructor(private stocksummary:StocksummaryService)
  {
    super();
  }
  connect(): Observable<Quote[]>
  {
   var data = this.stocksummary.getStocks();
    console.log(data);
    return data;
  }



 disconnect(){}
}



const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  })
}

@Injectable({
  providedIn: 'root'
})
export class StocksummaryService {
  quote:Quote[] = [];
  constructor(private http:HttpClient) { }
  getStocks():Observable<Quote[]> {
  this.http.get<Quote>("https://api.iextrading.com/1.0/stock/market/batch?symbols=AABA,AAPL,ABBV&types=quote")
  .subscribe(data => {
          for (var key in data) {
            if (data.hasOwnProperty(key)) {
             this.quote.push(data[key]["quote"]);
            }
          }
        });
        return observableOf(this.quote);
  }

}


export interface Quote {
    symbol?:                string;
    companyName?:           string;
    primaryExchange?:       PrimaryExchange;
    sector?:                string;
    calculationPrice?:      CalculationPrice;
    open?:                  number;
    openTime?:              number;
    close?:                 number;
    closeTime?:             number;
    high?:                  number;
    low?:                   number;
    latestPrice?:           number;
    latestSource?:          LatestSource;
    latestTime?:            LatestTime;
    latestUpdate?:          number;
    latestVolume?:          number;
    iexRealtimePrice?:      null;
    iexRealtimeSize?:       null;
    iexLastUpdated?:        null;
    delayedPrice?:          number;
    delayedPriceTime?:      number;
    extendedPrice?:         number;
    extendedChange?:        number;
    extendedChangePercent?: number;
    extendedPriceTime?:     number;
    previousClose?:         number;
    change?:                number;
    changePercent?:         number;
    iexMarketPercent?:      null;
    iexVolume?:             null;
    avgTotalVolume?:        number;
    iexBidPrice?:           null;
    iexBidSize?:            null;
    iexAskPrice?:           null;
    iexAskSize?:            null;
    marketCap?:             number;
    peRatio?:               number | null;
    week52High?:            number;
    week52Low?:             number;
    ytdChange?:             number;
}
export enum CalculationPrice {
    Close = "close",
}

export enum LatestSource {
    Close = "Close",
}

export enum LatestTime {
    February82019 = "February 8, 2019",
    January292019 = "January 29, 2019",
}

export enum PrimaryExchange {
    NASDAQGlobalMarket = "NASDAQ Global Market",
    NYSEArca = "NYSE Arca",
    NasdaqGlobalSelect = "Nasdaq Global Select",
    NewYorkStockExchange = "New York Stock Exchange",
}



<table mat-table [dataSource]="dataSource"
class="mat-elevation-z4" >

<ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef> symbol </th>
    <td mat-cell *matCellDef="let item">
        {{item.symbol}} </td>
</ng-container>

<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns:
    displayedColumns;"></tr>
</table>

person Ownage    schedule 10.02.2019    source источник
comment
получает ли QuoteDataSource значение? может захотеть попробовать установить это из конструктора или ngoninit   -  person Craig    schedule 11.02.2019
comment
Я пробовал это и не получилось. Это может быть проблема асинхронности, но я не знаю, что делать.   -  person Ownage    schedule 11.02.2019
comment
в консоли ничего нет?   -  person Craig    schedule 11.02.2019


Ответы (1)


Проблема, с которой вы столкнулись, связана с тем, что вы подписываетесь на свой HTTP-запрос в своей службе, но затем возвращаете данные за пределами этой подписки (когда запрос, скорее всего, еще не был выполнен).

Я бы написал это так:

public getStocks(): Observable<Quote[]> {
  return this.http.get<Quote>("https://api.iextrading.com/1.0/stock/market/batch?symbols=AABA,AAPL,ABBV&types=quote")
    .pipe(map(data => {
      for (var key in data) {
        if (data.hasOwnProperty(key)) {
          this.quote.push(data[key]["quote"]);
        }
      }
      return this.quote;
    }));
}

Здесь мы делаем запрос, используем pipe и map для преобразования ваших данных так, как вы хотите, но на самом деле не подписывайтесь на них, это будет работа компонента / источника данных. Мы просто возвращаем этот Observable и все готово.

Также в вашем ngOnInit вы снова делаете аналогичную ошибку, вы подписываетесь на Observable и, не «ожидая» ответа, вы пытаетесь зарегистрировать возвращаемое значение, оно должно быть таким:

ngOnInit() {
  this.stocksummary.getStocks().subscribe(t => {
    this.quote = t;
    console.log(this.quote);
  });    
}

Вот рабочий стек, который показывает рабочую версию вашего кода.

person Fabian Küng    schedule 15.02.2019