Вложенные http-запросы с картой с rxjs в Angular2

Я новичок в Rxjs (и в Angular2 в целом), и мне трудно понять тонкости RxJS.

Я хочу сделать два REST-вызова GitLab API:

  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"
        }
    ]
    }

Итак, в основном мне нужно перебрать все идентификаторы, заданные первым запросом, и доставить массив сведений о группе:

[
 {
 "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, но никак не могу заставить это работать...


person Tim Plateus    schedule 19.04.2017    source источник


Ответы (2)


вы можете сделать что-то вроде этого

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))
person Tiep Phan    schedule 19.04.2017

Что-то подобное. Вам нужно заменить статический 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)) - для каждого пользователя вы создаете отдельный наблюдаемый
  2. .mergeMap для каждого наблюдаемого пользователя, которого вы вызываете $http для получения проектов.
person Julia Passynkova    schedule 19.04.2017