在Angular2中使用带有rxjs的映射嵌套的http请求

时间:2017-04-19 14:58:09

标签: angular gitlab rxjs angular2-observables

我是Rxjs(以及一般的Angular2)的新手,而且我无法理解RxJS的细微之处。

我想对GitLab API进行两次REST调用:

  1. 接收某个用户的所有组(通过gitlab.com/api/v4/groups)。这将给我一个像这样的JSON:

    [
    {
        "id": 1511397,
        "name": "some name",
        "parent_id": 1505403,
    ...
    },
    {
        "id": 1511403,
        "name": "some other name",
        "parent_id": 1505403,
    ...
    }
    ]
  2. 接收每组的所有项目(通过gitlab.com/api/v4/groups/:id),它们会为您提供1组的详细版本:

    {
    "id": 1511397,
    "name": "group name",
    "parent_id": 1505403,
    "projects": [
        {
            "id": 3099499,
            "description": "project 1"
        },
        {
            "id": 3099489,
            "description": "Project 2"
        }
    ]
    }
  3. 所以基本上我需要遍历第一个请求给出的所有ID,并提供一组组细节:

    [
     {
     "id": 1511397,
     "name": "group name",
     "parent_id": 1505403,
     "projects": [
         {
             "id": 3099499,
             "description": "project 1"
         },
         {
             "id": 3099489,
             "description": "Project 2"
         }
     ]
     },
     {
     "id": 1194997,
     "name": "a second group name",
     "parent_id": 152393,
     "projects": [
         {
             "id": 9423423,
             "description": "project 3"
         },
         {
             "id": 2394238,
             "description": "Project 4"
         }
     ]
     }
    ]
    

    如何做到这一点?我已经尝试了一些类似switchMap,concatMap和MergeMap的东西,但我从来没有让它工作......

2 个答案:

答案 0 :(得分:1)

你可以做这样的事情

getGroups() {
  return this.http.get('gitlab.com/api/v4/groups')
    .map(res => res.json()) // convert to object[]
    .map(res => res.map(g => g.id)) // get all id
    .mergeMap(gid => {
      let gs = [];
      gid.forEach(id => {
        let req = this.http.get(`gitlab.com/api/v4/groups/${id}`);
        gs.push(req);
      });
      return Observable.forkJoin(gs);
    })
    .map(res => { // we have array of Response Object
        return res.map(x => x.json()); // Array.map not Observable map operator.
    });
}

getGroups().subscribe(res => console.log(res))

答案 1 :(得分:0)

这样的事情。您需要将静态Observable.of替换为$ http observables。

Rx.Observable.of([{userId:1}, {userId:2}])
.switchMap(ids => Rx.Observable.of(...ids))
.mergeMap(userId => {
 return Rx.Observable.of([
   {userId:userId, name:'project1'},
   {userId:userId, name:'project2'}
 ]);
})
.subscribe(x=>console.log(x));
  1. Rx.Observable.of([{userId:1},{userId:2}]) - 就像http调用一样,为用户数组提供服务 2 .switchMap(ids => Rx.Observable.of(... ids)) - 为每个用户创建一个单独的observable
  2. .mergeMap为每个用户可观察到你调用$ http来获取项目。