带映射的儿童的Angular 8 http子请求

时间:2019-07-16 08:59:25

标签: angular rxjs observable angular8

我必须在一次对getTree()的调用中执行以下请求,该调用必须返回Observable<TreeNode>

  • 开始交易
  • 获取父节点(结果给了我一个带有孩子ID的数组)
    • 对于每个子ID,获取子节点并将数字替换为子对象
  • 结束交易

我对嵌套子地图请求有疑问

    getTree(): Observable<TreeNode> {
        return this.getTransactionId().pipe(
            concatMap(trx => {return this.getRootNode(trx, 50);}),
            tap(result => {this.transactionClose().subscribe()})
        ) as Observable<TreeNode>;
    }

    getRootNode(trx: number, nodeId: number): Observable<TreeNode> {
        this.log('fetching root node '+ nodeId);
        var urlRootNode = config['apiUrl'] + `/dataview/perspective/get_root_nodes/trx=${trx}&id=${nodeId}`;
        return this.http.get<TreeNode>(urlRootNode).pipe(
            map(data => { 
                this.log('got root node data ' + data);
                let node = data[0]; 
                node.children = node.children.map(id => {
                    return this.getNodeChild(trx, id).subscribe();
                    // this is where I need help, because
                    // right now, the subscriber of getTree gets notified before the children are loaded
                });


                return node;
            }),
            catchError(this.handleError<TreeNode>('getRootNode'))
        )
    }

    getNodeChild(trx: number, nodeId: number): Observable<TreeNode> {
        this.log('fetching node '+ nodeId);
        var urlNode = config['apiUrl'] + `/dataview/node/get_children/trx=${trx}&id=${nodeId}`;
        return this.http.get<TreeNode>(urlNode).pipe(
            map(data => { 
                this.log('got node data ' + data);
                let node = data[0];                 

                return node;
            }),
            catchError(this.handleError<TreeNode>('getNodeChild'))
        )
    }

1 个答案:

答案 0 :(得分:2)

我认为可以以另一种方式实现(更改:添加switchMap,返回来自压缩并映射的源)

getRootNode(trx: number, nodeId: number): Observable<TreeNode> {
    this.log('fetching root node '+ nodeId);
    var urlRootNode = config['apiUrl'] + `/dataview/perspective/get_root_nodes/trx=${trx}&id=${nodeId}`;
    return this.http.get<TreeNode>(urlRootNode).pipe(
        switchMap(data => { 
            this.log('got root node data ' + data);
            let node = data[0]; 
            let children$ = zip(...node.children.map(id => {
                return this.getNodeChild(trx, id)
            }));


            return children$.pipe(map(children => node.children = children), map(()=> node));
        }),
        catchError(this.handleError<TreeNode>('getRootNode'))
    )
}