我已经在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;
}
}
答案 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;
}
}