Javascript 在Angular 7中使用expand()和concatMap()递归
我有以下API列表:Javascript 在Angular 7中使用expand()和concatMap()递归,javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,我有以下API列表: 1. https://www.something.com/?filter=something Result: { id: 12 previous: null next: https://www.something.com/?filter=something&page=2 data: ... } 2. https://www.something.com/?filter=something&page=2 Result: { id
1. https://www.something.com/?filter=something
Result:
{
id: 12
previous: null
next: https://www.something.com/?filter=something&page=2
data: ...
}
2. https://www.something.com/?filter=something&page=2
Result:
{
id: 13
previous: https://www.something.com/?filter=something
next: https://www.something.com/?filter=something&page=3
data: ...
}
3. https://www.something.com/?filter=something&page=3
Result:
{
id: 14
previous: https://www.something.com/?filter=something&page=2
next: null
data: ...
}
在获取每个API调用的数据后,我想遍历所有URL,检查下一个变量是否为null。如果它不为null,它将继续运行。在执行过程中,每个API调用的数据都将是concat并返回到输出
这就是我到目前为止一直在尝试的
getByURL(url: string): any {
return this.apiService.get(url).pipe(map(data => data));
}
getData(): Observable<any> {
const url = 'https://www.something.com/?filter=something';
return this.getByURL(url).pipe(
expand(({ data }) => {
if (!data.next) return this.getByURL(data.next);
else return empty();
}),
concatMap(({ content }) => {
return of(content.data);
})
);
}
我想在每次请求后收集所有数据。请查看控制台以查看输出。我总是没有定义。谢谢
我修复了您的代码如下()
ngOnInit(){
this.getByPageNext()
.订阅(数据=>{
控制台日志(数据);
});
}
get(url:string):Observable'下一个url是http
而不是https
,这将导致HttpError->ProgressEvent
所以我从“”开始,其余的都很好。因此,在您更改后端以修复下一个链接后,再将其更改回原始请求
另一点是api返回的结果是数组而不是对象,这就是我访问result[0]
另一点是返回empty()的条件,反之亦然为什么不能将Json对象设置为数组并在其中循环?我已经考虑过了,我在想,为什么不使用键:每个请求之后的下一个。这就是我要做的。我最初的解决方案是:我自己生成了所有的url,并通过它循环并收集数据结果。另外,你的API不应该发送previous:null,当它为null时就不要发送previous我正在使用Django Rest Framework作为我的后端API。这些是我从框架中得到的。
http://5cf15627c936cb001450bd0a.mockapi.io/users
http://5cf15627c936cb001450bd0a.mockapi.io/users2
http://5cf15627c936cb001450bd0a.mockapi.io/users3
ngOnInit() {
this.getByPageNext()
.subscribe(data => {
console.log(data);
});
}
get(url: string): Observable<any> {
return this.httpClient
.get(url)
.pipe(catchError(this.formatErrors));
}
formatErrors(error: any) {
console.error('error', error);
return throwError(error.error);
}
getByURL(url: string): any {
return this.get(url);
}
getByPageNext(): Observable<any> {
const url = 'https://5cf15627c936cb001450bd0a.mockapi.io/users2';
return this.getByURL(url)
.pipe(
expand((response: Array<any>) => {
if (response && response.length && response[0].next) {
return this.getByURL(response[0].next);
}
else {
return empty()
}
}),
map(obj => obj[0]),
reduce((acc, x: any) => acc.concat([x.data]), []),
);
}