TypeError:无法读取未定义的属性“ food”

时间:2019-03-19 10:21:09

标签: angular

我已经在Angular中编写了一个简单的预算跟踪器应用程序,用于跟踪家庭的预算。用户可以添加费用,收入和经常性费用,以了解他们在一段时间内节省或损失了多少。

我希望能够将范围输入的值保存到localStorage,并且还可以使用ngMmodel将localStorage数据读取到范围输入中,但是出现以下错误:

ERROR TypeError: Cannot read property 'food' of undefined
    at Object.eval [as updateDirectives] (IncomeandexpensesComponent.html:37)

此stacktrace引用此行:

<input type="range" [(ngModel)]="budget.food" class="form-control-range slider" min="1" max="5000" id="foodinput"

这是一个Stackblitz:https://stackblitz.com/github/avaliaho/budgettracker,这是与该主题相关的代码:

incomeandexpenses.component.html:

<h3>Food costs in a month</h3>
<p class="lead">All food costs in a budget. Includes going to the grocery store
  and eating at work place, school, restaurants etc.</p>

<div class="form-group">
  <input type="range" [(ngModel)]="budget.food" 
class="form-control-range slider" min="1" max="5000" id="foodinput"
    oninput="foodoutput.value = foodinput.value">
  <output id="foodoutput">{{ budget.food }}</output>€
</div>

<button (click)="save()" type="button" class="btn btn-primary">Save</button>

incomeandexpenses.component.ts:

import { Component, OnInit } from '@angular/core';
import { BudgetService } from '../budget.service';
import { budget } from '../budget.interface';

@Component({
  selector: 'app-incomeandexpenses',
  templateUrl: './incomeandexpenses.component.html',
  styleUrls: ['./incomeandexpenses.component.css']
})
export class IncomeandexpensesComponent implements OnInit {

  budget = {
    month: new Date().getMonth(),
    income: 0,
    food: 0,
    drinks: 0,
    housing: 0,
    bills: 0,
    loans: 0,
    travel: 0,
    clothing: 0,
    insurances: 0,
    netflix: 0,
    hobby: 0,
    other: 0,
    date: new Date().getTime()
  } as budget;

  constructor(private service: BudgetService) { }

  ngOnInit() {
    this.budget = this.service.getMonth(new Date().getMonth());
  }

  save = () => {
    this.service.save(this.budget);
  }

}

budget.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { budget } from './budget.interface';

@Injectable()
export class BudgetService {

  constructor(private http: HttpClient) { }

  getMonth = (month: number): budget => {
    let budgets: budget[] = JSON.parse(localStorage.getItem("budgets"));

    if (budgets != null) {
      for (let budget of budgets) {
        if (budget.month == month) {
          return budget;
        }
      }
    }
  }

  getAll = () => {
    let budgets: budget[] = JSON.parse(localStorage.getItem("budgets"));

    if (budgets != null) {
      return budgets;
    }
  }

  save = (form: budget) => {

    let month: budget = {
      "month": form.month,
      "income": form.income,
      "food": form.food,
      "drinks": form.drinks,
      "housing": form.housing,
      "bills": form.bills,
      "loans": form.loans,
      "travel": form.travel,
      "clothing": form.clothing,
      "insurances": form.insurances,
      "netflix": form.netflix,
      "hobby": form.hobby,
      "other": form.other,
      "date": new Date().getTime()
    };

    let budgets: budget[] = JSON.parse(localStorage.getItem("budgets"))

    if (budgets == null) {
      budgets = [];
      budgets.push(month);
      localStorage.setItem("budgets", JSON.stringify(budgets))
    } else {
      budgets.forEach((budget, index) => {
        if (budget.month == form.month) {
          budgets[index] = month;
        }
      })

      localStorage.setItem("budgets", JSON.stringify(budgets))
    }
  }

  getDatePeriod = (beginDate: number, endDate: number): budget[] => {
    let budgets: budget[] = JSON.parse(localStorage.getItem("budgets"));
    let withinRange: budget[] = [];

    for (let budget of budgets) {
      if (budget.date >= beginDate && budget.date <= endDate) {
        withinRange.push(budget);
      }
    }
    return withinRange;
  }

}

3 个答案:

答案 0 :(得分:1)

在将数据分配给budget之前,请通过使用以下条件确保响应不是null或未定义,如果数据不可用(如以下所示),您可以向用户显示一些相关消息。

  ngOnInit() {
    let response = this.service.getMonth(new Date().getMonth());
    if(response) {
       this.budget = response;
    } else {
      alert('No Data available');
    }

  }

希望这会有所帮助!

答案 1 :(得分:0)

通常会出现此错误,因为模板是在初始化之前绘制数据的。 因此,您必须添加到模板* ngIf =“ budget”

答案 2 :(得分:0)

问题在于,在localStorage不包含getMonth()键的情况下,budgets方法返回一个空对象。要解决此错误,请将getMonth()方法更改为此:

getMonth = (month: number): budget => {
    let budgets: budget[] = JSON.parse(localStorage.getItem("budgets"));

    if (budgets != null) {
      for (let budget of budgets) {
        if (budget.month == month) {
          return budget;
        }
      }
    } else {
      let month = {
        month: new Date().getMonth(),
        income: 0,
        food: 0,
        drinks: 0,
        housing: 0,
        bills: 0,
        loans: 0,
        travel: 0,
        clothing: 0,
        insurances: 0,
        netflix: 0,
        hobby: 0,
        other: 0,
        date: new Date().getTime()
      } as budget;
      return month;
    }
  }