开发者问题收集

Angular - TypeError:无法读取未定义的属性(读取‘reduce’)

2021-10-30
6598

当我尝试执行此代码块时,我得到了以下结果。

发生错误的位置为第 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);

 }
2个回答

您收到此错误的原因是因为 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

Ran Turner
2021-10-30
// 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 回调

eroironico
2021-10-30