ОШИБКА TypeError: Невозможно прочитать свойство 'name' - Angular Material Table - PullRequest
0 голосов
/ 19 января 2019

Я посылаю несколько вызовов REST GET для извлечения данных из внешнего ресурса.

Я вижу запросы, отправленные и возвращенные с соответствующими данными. Но после последнего ответа я получаю: ОШИБКА TypeError: Невозможно прочитать свойство 'name' из неопределенного в Object.eval [как updateRenderer] (ProductcatalogComponent.html: 14)

Я предполагаю, что способ хранения данных - это неправильный способ сделать это при сборе нескольких вызовов ...

это функция из моего сервиса.ts

  getData() {
    return this.getProducts('/v1/catalog/products');
  }

 getProducts(url, dataSoFar = []): Observable<any[]> {
    if (!url) {
      return of (dataSoFar);
    } else {
      url = ZUORA_URL + url;
    }
    return this.http.get<any>(url, { headers }).pipe(
      switchMap(p => this.getProducts( p.nextPage, [...dataSoFar, ...p.data]))
    );
  }

а вот как я это называю из компонента:

  ngOnInit() {
    this.zuoraService.getData().subscribe(catalog => {
      this.dataSource = new MatTableDataSource(<Catalog[]>catalog);
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
    });
  }

это модель:

export interface Catalog {
  name: string;
  id: string;
  sku: string;
  description: string;
  IsTrialProduct__c: string;
}

и это HTML-файл

<div class="mat-horizontal-content-container">
  <h1><i class="material-icons">dvr</i> Productcatalog</h1>
</div>

<div class="mat-elevation-z8">
  <mat-form-field style="width: 100%">
    <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
  </mat-form-field>

  <table mat-table class="full-width-table" [dataSource]="dataSource" matSort aria-label="Elements">

    <ng-container matColumnDef="name">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
      <td mat-cell *matCellDef="let row">{{row.name}}</td>
    </ng-container>

    <ng-container matColumnDef="sku">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>
      <td mat-cell *matCellDef="let row">{{row.sku}}</td>
    </ng-container>

    <ng-container matColumnDef="description">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
        <td mat-cell *matCellDef="let row">{{row.description}}</td>
    </ng-container>

    <ng-container matColumnDef="IsTrialProduct__c">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Trial</th>
        <td mat-cell *matCellDef="let row">{{row.IsTrialProduct__c}}</td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="openAccountDetails(row.ID)"></tr>
  </table>

  <mat-paginator #paginator
      [length]="dataSource.data.length"
      [pageIndex]="0"
      [pageSize]="25"
      [pageSizeOptions]="[25, 50, 100, 250]">
  </mat-paginator>
</div>

Как я могу исправить проблему? Мне придется использовать данные на разных компонентах. Данные не будут часто меняться -> что будет лучшим способом предварительной выборки данных и их кэширования?

1 Ответ

0 голосов
/ 23 января 2019

изменил услугу:

public getCatalog() {
    console.log(this.catalog);
    return this.catalog;
  }

  loadCatalog() {
    this.fetchCatalog().subscribe(catalog => this.catalog.next(catalog));
  }

  public fetchCatalog(): Observable<Catalog[]> {
    return this.http.get<Catalog>(ZUORA_URL + '/v1/catalog/products?page=1&pageSize=10', { headers })
      .pipe(
        expand(catalog => {
          if (!catalog.nextPage) {
            return EMPTY;
          }
          return this.http.get<Catalog>(ZUORA_URL + catalog.nextPage, { headers });
        }),
        map(catalog => catalog.products),
        reduce((accData, data) => accData.concat(data), []),
      );
  }

добавил фабрику в app.module.ts -> данные загружаются один раз при сборке приложения -> данные не нужно перезагружать каждый раз, когда пользователь меняет представление

export function catalogProviderFactory(zuoraService: ZuoraService) {
  return () => zuoraService.loadCatalog();
}

Компонент OnInit для построения таблицы:

  ngOnInit() {
    this.zuoraService.catalog$.subscribe(catalog => {
      this.dataSource = new MatTableDataSource(catalog);
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
    });
...