Angular5 - 无法按预期使用Object.keys

时间:2018-01-12 20:18:55

标签: angular object

我正在开发一个应用程序,我从私有git企业服务器中提取数据。我有一个字符串数组供repos检查,我将这些数据与一些来自本地JSON文件的数据结合起来给我一个像这样的结构:

{ 
  repo1: {},
  repo2: {},
  repo3: {}
}

对象的回归与我期望的完全一样。问题是当我想得到一个计数。通常在JS中我使用Object.keys,但是当我这样做时返回一个空数组。我通过创建一个本地数组并将名称推入其中来暂时解决这个问题,因此我可以使用ngFor进行迭代。我挖的越多,它的意义就越小。我可以在对象文字上使用Object.keys,或者在没有问题的情况下使用我的预定义对象。问题是当我尝试在这个返回的对象上使用它时。我正在运行代码以获取ngOnInit()中的对象。当我在console.log中时它返回的对象完全符合预期,但如果我将日志更改为Object.keys(object),则返回空白。我想也许这是一个时间问题,所以我把这个函数包装在一个承诺中,然后将它链接起来。然后关闭它。同样,promise返回的对象看起来是正确的,但是我不能在它上面使用Object.keys。我也试过返回Object.keys(对象)而不是函数中的对象,但它仍然是空白的。

我有什么遗失的吗?是否有更多的角色'处理这个的方法?我已经使用Angular了一段时间但从未碰到过这样的事情。想知道它是时间问题还是什么。

tabContentSetup(tabArray) {
const filteredObject = {};
const filteredArray = [];
// For each element in the array, get the repo name
tabArray.forEach((repo) => {
  // Grab all prs for the current repo
  this.gitApiService.getPrs(repo)
    // Subscribe to observable which returns an array of PR objects from the repo
    .subscribe((prObjectArray) => {
      // Iterate over each prObject in prObjectArray
      prObjectArray.forEach((prObject) => {
        // Grab the github user that submitted PR in lowercase
        const prObjectUser = prObject.user.login.toLowerCase();
        // If this PR belongs to a consultant, disregard and return
        if (this.instructorsArray.includes(prObjectUser)) {
          return;
        }
        // If filteredObject does not have the current repo yet, add it as a new object
        if (!filteredObject[repo]) {
          filteredObject[repo] = {
            count: 1,
            cohortsArray: [],  // TODO fix this with Object.keys
            cohorts: {}
          };
          filteredArray.push(repo); // TODO find out why Object.keys isn't working
        } else {
          filteredObject[repo]['count']++; // TODO could be shortened with Object.keys
        }
        if (this.gitHubDict[prObjectUser] === undefined) {
          console.warn('Cannot find: ' + prObjectUser + ' in Cohort JSON files');
          return;
        }
        const assignedCohort = this.gitHubDict[prObjectUser].cohort;
        if (!filteredObject[repo]['cohorts'][assignedCohort]) {
          filteredObject[repo].cohortsArray.push(assignedCohort);
          filteredObject[repo]['cohorts'][assignedCohort] = {
            count: 1,
            prs: []
          };
        } else {
          filteredObject[repo]['cohorts'][assignedCohort].count++;
        }
        filteredObject[repo]['cohorts'][assignedCohort]['prs'].push({
          name: this.gitHubDict[prObjectUser].first + ' ' + this.gitHubDict[prObjectUser].last,
          cohort: assignedCohort,
          git: prObjectUser,
          url: prObject.html_url,
          created_at: prObject.created_at,
          updated_at: prObject.updated_at
        });
        });
    });
});
return Object.keys(filteredObject);
}

这太长了,这就是我回去尝试使用Object.keys进行重构的原因。

1 个答案:

答案 0 :(得分:0)

返回不会在订阅者上等待,因此filteredObject为空。你应该让filteredObject成为一个Observable(或者更确切地说是一个Subject)并订阅它。这部分代码在方法调用上按顺序执行:

const filteredObject = {};
const filteredArray = [];
tabArray.forEach((repo) => {
    this.gitApiService.getPrs(repo).subscribe();
}
return Object.keys(filteredObject);

subscribe()触发返回的observable中的getPrs()时,我会执行next()回调方法中的部分(我猜你会返回HttpClient.get()?)。因此,在调用tabContentSetup()时,它将返回一个空对象,因为HTTP请求尚未完成。

我建议使用BehaviorSubject(请参阅此答案:BehaviorSubject vs Observable?)。在函数外部声明filteredObject并使用内置的getter .value和“setter”.next()

// initialize a Subject with an empty object
filteredObjectObservable = new BehaviorSubject({});
// initialize a public variable for the count
repoCount: number;

tabContentSetup(tabArray) {
    tabArray.forEach((repo) => {
        this.gitApiService.getPrs(repo).subscribe((prObjectArray) => {
              // set the variable here and use the built in getter, to get the current value
              let filteredObject = this.filteredObjectObservable.value;
              // do your stuff

              // at the very end of the subscribe callback, set the new value. This will also trigger all subscribers
              this.filteredObjectObservable.next(filteredObject);
        }
    }
    // subscribe to the BehaviorSubject (this could also be in the component's OnInit method or anywhere else).
    this.filteredObjectObservable.subscribe((value) => {
        // triggers each time the Subject's next() method is called
        this.repoCount = Object.keys(value).length;
    }
}

注意:代码未经测试: - )