在打印mat-tab之前,我需要使用用户及其位置构建一个数组。
在我的组件中:
public userWithLocations = [];
ngOnInit () {
this.loadData();
}
loadData() {
let that = this;
// get all users
this.httpSrv.getAllUsers()
.subscribe(allUser => {
for (let user in allUser) {
let currentUser = allUser[user];
// get locations by user
this.httpSrv.getLocationsByUser(allUser[user]['_id'])
.subscribe((locations) => {
currentUser.nb_location = locations;
that.userWithLocations.push(currentUser);
})
}
console.log(that.userWithLocations); // => []
// Here i need my array with for each user an attribute with locations count
// init MatTableDataSource dataSource only when receive data (NOT BEFORE)!
this.dataSource = new MatTableDataSource(that.userWithLocations);
// init paginator
this.dataSource.paginator = this.paginator;
// // init sort
this.dataSource.sort = this.sort;
});
}
在我的服务(http)中:
// Users requests
getAllUsers(): Observable<any> {
// return Observable
return this.http.get(this.apiURL + 'users');
}
getLocationsByUser(id): Observable<any> {
// return Observable
return this.http.get(this.apiURL + '/locations/' + id)
.pipe(map(locations => { return this.size(locations)}));
}
// Object length
size(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
我是年轻的开发人员,是angular 6的初学者,我尝试学习如何使用rxjs做嵌套调用api。
Angular version: X.Y.Z
> Angular CLI: 6.0.8
> Node: 10.4.0
> OS: darwin x64
> Angular: 6.0.4
>
> Package Version
> -----------------------------------------------------------
> @angular-devkit/architect 0.6.8
> @angular-devkit/build-angular 0.6.8
> @angular-devkit/build-optimizer 0.6.8
> @angular-devkit/core 0.6.8
> @angular-devkit/schematics 0.6.8
> @angular/animations 6.0.5
> @angular/cdk 6.2.1
> @angular/cli 6.0.8
> @angular/flex-layout 6.0.0-beta.15
> @angular/material 6.2.1
> @ngtools/webpack 6.0.8
> @schematics/angular 0.6.8
> @schematics/update 0.6.8
> rxjs 6.2.1
> typescript 2.7.2
> webpack 4.8.3
Browser:
- [x] Chrome (desktop) Version 68.0.3440.84
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node: 10.4.0
- Platform: Mac
Others:
答案 0 :(得分:3)
代码中的一个问题是您在订阅中进行订阅。这是必须避免的事情。明显是滥用RxJ的迹象。
使用RxJ的正确方法更多是这样的
this.httpSrv.getAllUsers()
.pipe(
map(users => from(users)),
mergeMap(user => this.httpSrv.getLocationsByUser(user[_id])
.pipe(
tap(locations => user.nb_location = locations;
)
),
toArray()
)
.subscribe(userWithLocations => {// do what you need to do})
这段代码基本上是
map
和from
mergeMap
和
以下通过管道tap
toArray
转换数组中的用户流您的原始代码中的问题是,由于http调用的异步特性,当退出for
循环时,尚未执行用于获取位置的各种调用。他们将在一段时间后返回结果。同时,您的userWithLocations
显然是一个空数组。
我建议您花一些时间研究RxJ,并了解其机制。即使没有在Angular的上下文中,this is an article也会解释我在工作之前谈论过的运算符。