对子组件的角度传递API响应

时间:2019-07-16 14:17:24

标签: angular typescript rest api

我有一个“仪表板”组件和一个“ Dashboard-InfoBox”子组件。 在我的Dashboard组件中,我在服务中调用一个函数,该函数返回API响应,然后创建一个变量,该变量保存所需的数据并将其传递给Dashboard-InfoBox进行渲染。

问题是Dashboard-infobox尝试访问尚不存在的数据,这会在我的控制台中导致错误。

我曾尝试包含* ngIf =“ marketData ['HENRYHUB']”,但是ngIf不会在数据到来时呈现它。

market.service.ts


  getHenryHub() {
    const henryHubCache = this.responseCache.get(this.henryHubURL);
    if(henryHubCache) {
      console.log(henryHubCache);
      return of(henryHubCache);
    }
    const response = this.http.get<EiaResponse>(this.henryHubURL);
    response.subscribe(res => this.responseCache.set(this.henryHubURL, res));
    return response;
  }

dashboard.component.ts

this.marketData = {} as IDictionary;

    this.marketDataService.getHenryHub().subscribe(res => {
      let henryHub = {
        date: res["series"][0].data[0][0],
        price: res["series"][0].data[0][1].toFixed(2),
        status: res["series"][0].data[0][1] > res["series"][0].data[1][1] ? true : false,
      }
    this.marketData['HENRYHUB'] = henryHub;
    });

dashboard-infobox.component.ts

  @Input() marketData: any;

        <div *ngIf="marketData" class="tab-wrapper" style="float: right">
    <div class="exchange" style="border-bottom: 1px solid #1e6ec8;">
        <p style="font-weight: 600; margin: auto;">
            Gas/Oil Prices
        </p>
    </div>

    <div class="exchange" *ngIf="marketData.BRENT">
        <p style="flex: 0 0 30%; margin-left: 15px;">
            Brent Oil
        </p>
        <img matListAvatar [src]="marketData.BRENT.status ? 'assets/img/up.png' : 'assets/img/down.png'" style="width: 20px" />
        <p style="flex: 0 0 40%; margin-left: 15px;">
            {{ marketData.BRENT.price }} $/Bbl
        </p>
        <p>
            {{ date | date: 'MMM dd' }}
        </p>
    </div>

    <div class="exchange" *ngIf="marketData.HENRYHUB">
        <p style="flex: 0 0 30%; margin-left: 15px;">
            Henry Hub
        </p>
        <img matListAvatar [src]="marketData.HENRYHUB.status ? 'assets/img/up.png' : 'assets/img/down.png'" style="width: 20px" />
        <p style="flex: 0 0 40%; margin-left: 15px;">
            {{ marketData.HENRYHUB.price }} $/MMBtu
        </p>
        <p>
            {{ date | date: 'MMM dd' }}
        </p>
    </div>

    <div class="exchange" *ngIf="marketData.NBP">
        <p style="flex: 0 0 30%; margin-left: 15px;">
            NBP
        </p>
        <img matListAvatar [src]="marketData.NBP.status ? 'assets/img/up.png' : 'assets/img/down.png'" style="width: 20px" />
        <p style="flex: 0 0 40%; margin-left: 15px;">
            {{ marketData.NBP.price }} $/MMBtu
        </p>
        <p>
            {{ date | date: 'MMM dd' }}
        </p>
    </div>

    <div class="exchange" *ngIf="marketData.TTF">
        <p style="flex: 0 0 30%; margin-left: 15px;">
            TTF
        </p>
        <img matListAvatar [src]="marketData.TTF.status ? 'assets/img/up.png' : 'assets/img/down.png'" style="width: 20px" />
        <p style="flex: 0 0 40%; margin-left: 15px;">
            {{ marketData.TTF.price }} $/MMBtu
        </p>
        <p>
            {{ date | date: 'MMM dd' }}
        </p>
    </div>

    <div class="exchange" *ngIf="marketData.GASOIL">
        <p style="flex: 0 0 30%; margin-left: 15px;">
            Gas Oil
        </p>
        <img matListAvatar [src]="marketData.GASOIL.status ? 'assets/img/up.png' : 'assets/img/down.png'" style="width: 20px" />
        <p style="flex: 0 0 40%; margin-left: 15px;">
            {{ marketData.GASOIL.price }} $/Mt
        </p>
        <p>
            {{ date | date: 'MMM dd' }}
        </p>
    </div>
</div>

错误TypeError:无法读取未定义的属性“价格”

对于每个这些变量,我在控制台中都遇到4个错误。但是,在我的仪表板上,所有内容都完全按照我想要的方式显示。

2 个答案:

答案 0 :(得分:0)

只需对照您初始化为{}(不是null)的marketData变量检查ng-if

<div class="exchange" *ngIf="markedData && marketData !== {}">
      <p style="flex: 0 0 30%; margin-left: 15px;">
          Henry Hub
      </p>
      <img *ngIf="marketData['HENRYHUB'].status" matListAvatar 
        [src]="'assets/img/up.png'" 
        style="width: 20px"
        />
      <img *ngIf="!marketData['HENRYHUB'].status" matListAvatar 
        [src]="'assets/img/down.png'" 
        style="width: 20px"
        />
      <p style="flex: 0 0 40%; margin-left: 15px;">
      {{ marketData['HENRYHUB'].price }} $/MMBtu
      </p>
      <p>
      {{ date | date: 'MMM dd' }}
      </p>
    </div>

您会遇到错误,因为当Angular Firsts检查变量为null时,changeDetection会起作用并将值传递给您的孩子,因此所有内容都会呈现

答案 1 :(得分:0)

在信息中心信息框的组件模板中,使用*ngIf将div包裹在编辑问题之前的操作中。

加上,您只需一个img标签而不是两个标签就可以了。无论如何,您都在有条件地显示它们。

在这里,尝试一下:

<div class="exchange" *ngIf="marketData.HENRYHUB">
  <p style="flex: 0 0 30%; margin-left: 15px;">
    Henry Hub
  </p>
  <img 
    matListAvatar 
    [src]="marketData.HENRYHUB.status ? 'assets/img/up.png' : 'assets/img/down.png'" 
    style="width: 20px" />
  <p style="flex: 0 0 40%; margin-left: 15px;">
    {{ marketData.HENRYHUB.price }} $/MMBtu
  </p>
  <p>
    {{ date | date: 'MMM dd' }}
  </p>
</div>