Nested Observable with unknown nesting depth

空扰寡人 提交于 2019-12-13 03:28:49

问题


When sending a Get request to Sharepoint URI (e.g. http://company.com.au/teams/Telstra/_api/web/Lists/getbytitle('${listTitle}')/items), it returns a finite number of items (e.g. 30) and provides a link to query to retrieve the next 30 items like so:

I am writing an Angular app to retrieve all items. The pseudo code is like so:

public GetByDomainOwner(listTitle: string, domainNameOwner: string): Observable<any[]> {

    let dataToReturn = new Array<any>();

    let URI = `http://company.com.au/teams/Telstra/_api/web/Lists/getbytitle('${listTitle}')/items?$filter=DomainOwnerText eq '${domainNameOwner}'`;

    var headers: HttpHeaders = new HttpHeaders();
    headers.append('Accept', 'application/json;odata=verbose');

    while(URI !== undefined){
        const records = this.http.get(URI, {
            headers: headers,
            withCredentials: true
        });

        records.subscribe(r => {
            let data = <SharepointItem> r;

            dataToReturn.push(data.d.results);

            if(data.d.__next){
                URI = data.d.__next;
            } else{
                URI = undefined;
            }
        });
    }       

    console.log("Escaped while loop");

    return new Observable<any[]>(dataToReturn); // This is invalid obviously, but it describes how I want to make one Observable call to retrieve all data.
}

I want to make the above one single Observable call where it will read and subscribe to d.__next to retrieve the next finite number of items

Using Observable flatmap seems to be quite promising for situations where the depth of nesting is known (e.g. C subscribes to B's stream, of which B subscribes to A's stream). I want to make a flatMap (open to other suggestions) that can repeatedly check and subscribe to more streams without specifying a depth.


回答1:


As @KiraAG commented, expand is probably what you want.

This blog post should have the details you are after: https://blog.angularindepth.com/rxjs-understanding-expand-a5f8b41a3602

The key part is:

import { empty } from "rxjs/observable/empty";
import { concatMap, expand } from "rxjs/operators";
import { get } from "./get";

const url = "https://api.github.com/users/sindresorhus/repos";
const repos = get(url).pipe(
  expand(({ next }) => next ? get(next) : empty()),
  concatMap(({ content }) => content)
);
repos.subscribe(repo => console.log(repo));

where get(url) returns an observable with the ajax results (content) and the "next" url (to get the next results - held in __next in your example)



来源:https://stackoverflow.com/questions/56520156/nested-observable-with-unknown-nesting-depth

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!