Angular - TypeError:无法读取未定义的属性(读取‘reduce’)
当我尝试执行此代码块时,我得到了以下结果。
发生错误的位置为第 82 行: var group = this.detailsDate.reduce(function (r, o){
core.js:6486 ERROR TypeError:无法读取未定义的属性(读取“reduce”) at DashboardComponent.getDatesOnly (dashboard.component.ts:82) at DashboardComponent.ngOnInit (dashboard.component.ts:56)
getDatesOnly(){
this.requestService.getAllRequests().subscribe(data=>{
JSON.stringify(data);
this.requestAllDetails=data
var alldates = this.requestAllDetails.map(t=>t.startDate)
this.detailsDate = alldates;
console.log(alldates)
})
//above code returns array containing dates only
//returns array with month + count
var monthNames = [
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December"
];
var group = this.detailsDate.reduce(function (r, o){
var date = new Date(o);
var month = date.getMonth();
var monthName = monthNames[month];
(r[monthName]) ? r[monthName].count++ : r[monthName] = { monthName: monthName, count: 1 };
return r;
}, {});
var result = Object.keys(group).map((key) => group[key]);
console.log(result);
}
您收到此错误的原因是因为
detailsDate
在订阅方法中填充了数据,这意味着此代码不是同步的。
观察者
模式是 Angular 中采用的一种软件设计模式,其中一个名为主题的对象维护其依赖项列表,称为观察者,并自动通知它们任何状态变化。此模式实际上非常类似于发布/订阅设计模式(通常通过 Kafka 或 Azure 服务总线等消息队列在服务器中实现)。
可观察对象是声明性的,这意味着您定义一个用于发布值的函数,但直到消费者订阅它时才会执行。订阅的消费者随后会收到通知,直到函数完成(或直到他们取消订阅)。
订阅用于处理异步方法调用。因此,
subscribe()
方法中的代码仅在异步方法返回其结果时执行(例如在 http 调用之后)。在等待异步响应时,程序继续并执行以下代码,这就是您的代码无法按预期工作的原因。
您可以将减少逻辑移动到订阅以使其正常工作。
getDatesOnly(){
var monthNames = [
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December"
];
this.requestService.getAllRequests().subscribe(data=>{
JSON.stringify(data);
this.requestAllDetails=data
var alldates = this.requestAllDetails.map(t=>t.startDate)
this.detailsDate = alldates;
console.log(alldates)
var group = this.detailsDate.reduce(function (r, o){
var date = new Date(o);
var month = date.getMonth();
var monthName = monthNames[month];
(r[monthName]) ? r[monthName].count++ : r[monthName] = { monthName: monthName, count: 1 };
return r;
}, {});
var result = Object.keys(group).map((key) => group[key]);
console.log(result);
})
}
有关可观察对象和订阅者的更多信息,请参见此处 - https://angular.io/guide/observables
// Top of your file
const monthNames = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
];
class YourComponent ... {
getDatesOnly(){
this.requestService
.getAllRequests()
.subscribe(data => {
this.requestAllDetails = [...data] // You didn't specified but i pretend this is an array
const alldates = this.requestAllDetails.map(t => t.startDate)
this.detailsDate = allDates.reduce(function (r, o){
const date = new Date(o);
const month = date.getMonth();
const monthName = monthNames[month];
(r[monthName]) ? r[monthName].count++ : r[monthName] = { monthName: monthName, count: 1 };
return r;
}, {});
const result = Object.keys(this.detailsDate).map((key) => group[key]);
console.log(result);
});
}
subscribe 方法是异步的,这意味着你的代码首先执行 reduce,然后才执行 subscribe 回调