Angular: 加载组件时,数据给我 undefined

Angular: When loading a component, the data is giving me undefined

我犹豫要不要问这个问题,因为我知道答案将是非常明显的,而且直面我的面孔,但是在与代码抗争了 2 天之后,我快要拔头发了。

我是 angular 的新手(仅供参考),但对它背后的概念并不陌生。我构建了一个小型应用程序,它试图从另一台服务器上托管的 API 读取数据(可能),这会向我发送回 json object。然后 object 填充组件。这是一些示例代码:

页面服务

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';

import { Observable } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

import { HttpErrorHandler, HandleError } from './http-error-handler.service';
import { AlcalaPage } from '../../shared/models/alcala-page.model';
import { environment } from '../../../environments/environment';

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

@Injectable()
export class PageService {
  pageServiceUrl: string;
  private handleError: HandleError

  constructor(private http: HttpClient, private httpErrorHandler: HttpErrorHandler) {
    this.pageServiceUrl = environment.apiUrl + 'page/';
    this.handleError = httpErrorHandler.createHandleError('PageService');
  }

  getPage(pageid: string): Observable<AlcalaPage> {
    return this.http.get<AlcalaPage>(this.pageServiceUrl + pageid)
      .pipe(
          tap(data => console.log('Data is ' + data.months[0].expenses[0].entryType)),
          catchError(this.handleError('getPage', null))
        );
  }
}

page.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { environment } from '../../../environments/environment';

import { AlcalaPage } from '../../shared/models/alcala-page.model';
import { PageService } from '../service/page.service';

@Component({
  selector: 'app-page',
  templateUrl: './page.component.html',
  styleUrls: ['./page.component.scss']
})
export class PageComponent implements OnInit {
  pageid: string;
  imageurl: string;
  dataModel: AlcalaPage;
  public apiData;
  constructor(private route: ActivatedRoute, private pageService: PageService) {
  }

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.pageid = params['id'];
    });
    this.getPage();
    this.imageurl = environment.imageUrl + this.pageid + '.jpg';
  }

  getPage(): void {
    this.pageService.getPage(this.pageid)
      .subscribe(
        data => { this.dataModel = data; },
        err => console.error(err),
        () => console.log('page data loaded.')
        );
  }
}

page.component.html

<div class="container" fxLayout="row" fxLayout.xs="column" fxLayoutGap="0.5%" fxLayoutAlign="left">
  <div fxFlex="70%">
    <h2 class="right-align">{{dataModel.year}}</h2>
    <mat-tab-group>
      <mat-tab label="English">
        <div *ngFor="let month of dataModel.months">
          <app-month [dataModel]="month" currentLang="en"></app-month>
        </div>
      </mat-tab>
      <mat-tab label="Spanish">
        <div *ngFor="let month of dataModel.months">
          <app-month [dataModel]="month" currentLang="es"></app-month>
        </div>
      </mat-tab>
    </mat-tab-group>
  </div>
  <div fxFlex="20%">
    <ngx-imageviewer [src]="this.imageurl"></ngx-imageviewer>
  </div>
</div>

问题似乎源于页面的生命周期和我对生命周期如何移动的(明显的)误解。截至目前,页面上的年份字段正在加载 (<h2 class="right-align">{{dataModel.year}}</h2>),选项卡组显示为 header(所以我看到 "English" 的选项卡和 "Spanish" 但没有其他内容正在加载。当我检查控制台时,我看到一条错误消息,指出无法读取未定义的 属性 "months"。我发现此错误消息令人困惑有两个原因:

  1. dataModel(其中 months 是成员)显然不是未定义的,因为我能够在标签中呈现 dataModel.year。
  2. dataModel.months 中肯定有数据,因为当服务从服务器加载数据时,我能够将各种值写到控制台(我尝试记录 json object 到控制台,这样我就可以确保我的所有数据都存在)。

我的猜测是 a) 我在标签的 *ngFor 循环中做错了什么或者 b) 我在页面生命周期中遗漏了一些东西。但我不知道我可能做错了什么,因为我遵循和查看的所有教程似乎都按照我实施的方式做事。任何对我可能做错的事情有任何想法的人将不胜感激。

它是异步加载的,所以最初它是未定义的。

尝试做 let month of dataModel?.month,如果设置了 dataModel,它只会读取 monthhttps://angular.io/guide/template-syntax#the-safe-navigation-operator----and-null-property-paths