【问题标题】:ERROR TypeError:Cannot read property 'forEach' of undefined in Angular错误类型错误:无法读取 Angular 中未定义的属性“forEach”
【发布时间】:2020-07-14 14:08:59
【问题描述】:

我尝试使用 Angular 和 API 制作一个 highchart 应用程序,但我不知道为什么会出现此错误:ERROR TypeError: Cannot read property 'forEach' of undefined at DashboardComponent.GetProfitLossChart (47)。我没有我的代码中有任何错误,但我在 google chrome 页面中收到此错误。

这是我的 DashboardComponent.ts。

import { Component, OnInit } from '@angular/core';
import {Stockmodel} from '../model/stockmodel';
import { StockService } from '../services/stock.service';
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import * as Highcharts from 'highcharts';
import { debug } from 'util';

@Component({
 selector: 'app-dashboard',
 templateUrl: './dashboard.component.html',
 styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
 addForm: FormGroup;
 url: string = 'http://localhost:44311/api/GetStockData';
 Stocks:Stockmodel[];
 PortfolioStocks : Stockmodel[];
 constructor(private stockService: StockService, private formBuilder: FormBuilder) {
 }
ngOnInit() {
 // this.GetActiveStocks();
 this.GetDashboardPortfolioData();
 }
 GetDashboardPortfolioData()
 {
 this.stockService.GetStocks("http://localhost:44311/api/GetDashboardPortfolioData")
 .toPromise().then(data => {
 return this.PortfolioStocks = data;
 });
 }
 public profitLossChart: any = {
    chart: {
    type: 'pie',
    },
    title: {
    text: 'Profit/Loss Chart'
    },
    credits: {
    enabled: false
    },
    series: [],
   }
 
    GetProfitLossChart(){
    let totalInvestment:number=0;
    let totalGain:number=0;
    this.PortfolioStocks.forEach(row => {
    totalInvestment+=row.TotalInvested;
    totalGain += row.CurrentValue;
    });
    this.GetTopGainerChart();
    this.GetTopLoserChart();
    this.profitLossChart.series =[{
    data: [{
    name: 'Total Investment#',
    y: totalInvestment,
    },
    {
    name: 'Current Value',
    y: totalGain,
    }]
    }]
    Highcharts.chart('containerProfitLoss', this.profitLossChart);
 }
 public topGainerChart: any = {
 chart: {
 type: 'line',
 },
 title: {
 text: 'Top Gainer'
 },
 credits: {
 enabled: false
 },
 xAxis: {
 categories: [],
 },
 yAxis: {
 title: {
 text: ''
 },
 },
 series: [],
}
 GetTopGainerChart() {
 let length = this.PortfolioStocks.length;
 if (length > 0) {
 this.stockService.GetGainerLoserStockData('http://localhost:44311/api/GetGainerLoserStockData', this.
PortfolioStocks[length - 1].StockId, "Monthly")
 .toPromise().then(data => {
    const stockData = [];
    const dates = [];
    data.forEach(row => {
    const temp_row = [
    row.High,
    ];
    dates.push(row.Date);
    stockData.push(row.High);
    });
    var dataSeries = [];
    for (var i = 0; i < stockData.length; i++) {
    dataSeries.push(
    stockData[i]
    );
    }
    this.topGainerChart.series = [{ data: dataSeries, name:
   this.PortfolioStocks[length - 1].StockId }]
    this.topGainerChart.xAxis.categories = dates
    Highcharts.chart('topGainerChart', this.
   topGainerChart);
    },
    error => {
    console.log('Something went wrong.');
    });
    }
    }
    public topLoserChart: any = {
    chart: {
    type: 'line',
    },
    title: {
        text: 'Top Loser'
        },
        credits: {
        enabled: false
        },
        xAxis: {
        categories: [],
        },
        yAxis: {
        title: {
        text: ''
        },
        },
        series: [],
        }
        GetTopLoserChart() {
        let length = this.PortfolioStocks.length;
        if (length > 0) {
        this.stockService.GetGainerLoserStockData('http://localhost:44311/api/GetGainerLoserStockData',
       this.PortfolioStocks[0].StockId, "Monthly")
        .toPromise().then(data => {
        const stockData = [];
        const dates = [];
        data.forEach(row => {
        const temp_row = [
        row.High,
        ];
        dates.push(row.Date);
 stockData.push(row.High);
 });
 var dataSeries = [];
 for (var i = 0; i < stockData.length; i++) {
 dataSeries.push(
 stockData[i]
 );
 }
 this.topLoserChart.series = [{ data: dataSeries,
name: this.PortfolioStocks[0].StockId }]
 this.topLoserChart.xAxis.categories = dates
 Highcharts.chart('topLoserChart', this.topLoserChart);
 },
 error => {
 console.log('Something went wrong.');
 });
 }
 }
}

【问题讨论】:

  • 请检查调用 GetProfitLossChart() 时 this.PortfolioStocks 的值是多少。可能它为 null 或未定义。
  • 你的索引很糟糕
  • 谢谢,this.PortfolioStocks 为空。

标签: javascript angular highcharts


【解决方案1】:

我不确定这里,但您没有安全检查承诺返回的data。那是错误发生的地方吗?如果data 未定义,data.forEach 将抛出错误。

【讨论】:

  • 我在这一行得到错误“ this.PortfolioStocks.forEach(row => { ".
  • 可能是代码在承诺解决之前运行?您在承诺中设置了this. PortfolioStocks = data;
【解决方案2】:

尝试调试

.toPromise().then(data => {
    //console.log(data)
)}

可能是响应体里面的东西

{
  data: {},
  status: 200
}

所以您需要通过以下方式访问数据:

.toPromise().then(data => {
   //console.log(data?.data)
)}

【讨论】:

    【解决方案3】:

    您正在异步方法中设置PortfolioStocks,这意味着您不确定在执行forEach 时是否设置了该值。

    我建议您使用BehaviorSubject 方法和rxjs

    ...
    PortfolioStocks = new BehaviorSubject<Arry<Stockmodel>([]);
    ...
     GetDashboardPortfolioData() {
         this.stockService.GetStocks("http://localhost:44311/api/GetDashboardPortfolioData")
             .toPromise().then(data => {
                 this.PortfolioStocks.next(data);
              });
     }
    ...
        this.PortfolioStocks.pipe(filter(portfolioStocks => Array.isArray(portfolioStocks)))
            .subscribe(portfolioStocks => {
                portfolioStocks.forEach(row => {
                    totalInvestment+=row.TotalInvested;
                    totalGain += row.CurrentValue;
                });
            })
    
    
    
    

    【讨论】:

      猜你喜欢
      • 2018-07-12
      • 2021-12-16
      • 2021-11-05
      • 1970-01-01
      • 2019-04-15
      • 2018-11-21
      • 2020-05-25
      • 2019-03-13
      • 2018-08-29
      相关资源
      最近更新 更多