Как загрузить дополнительные данные для коллекции с помощью rxjs - PullRequest
1 голос
/ 09 июля 2020

Я изо всех сил пытаюсь понять различные операторы rx js. Например, когда у меня есть коллекция объектов, и я хочу добавить дополнительные данные из API к каждому объекту.

например

people = [{id: 1, name: null}, {id:2, name: null}]
from(people).pipe(
  map(person => {
    return api.getName(person.id).pipe(
      map(name => person.name = name)
    )
  })
).subscribe(people =>
  console.log(people) // should be [{id: 1, name: bob}, {id:2, name: alice}]
)

Я пробовал использовать mergeMap, map, switchMap в разных вариантах, но так и не понял, как получить отображение дополнительных данных в массиве.

Ответы [ 2 ]

4 голосов
/ 09 июля 2020

Вероятно, ваша проблема, когда вы используете карту / карту переключения, вы возвращаете результат назначения person.name = name;

Когда вы используете стрелочную функцию без фигурных скобок, подобных этой

() => something;

На самом деле это сокращение для

() => {
  return something
}

Вот рабочий пример с некорректным созданием класса, чтобы заставить его работать ... https://stackblitz.com/edit/angular-ivy-xfunnc?file=src%2Fapp%2Fapp.component.ts

  people = [{id: 1, name: null}, {id:2, name: null}];
  peopleWithNames = from(this.people).pipe(
    switchMap(person => {
      return this.api.getName(person.id).pipe(
        map(name => {
          // set the person's name property
          person.name = name;
          // but return the whole person object, not just the retrun from the assignment
          return person;
        })
      )
    })
  ).subscribe(p => {
    console.log(p)
  })

0 голосов
/ 09 июля 2020

Если вам нужен список, я думаю, вам нужно использовать forkJoin. Вы сопоставляете каждый элемент людей с вызовом

people = [{id: 1, name: null}, {id:2, name: null}];
forkJoin(people.map(p=>this.api.getName(person.id))
    .subscribe((res:any[])=>{
       res.forEach((p:any,index)=>{
         people[index]={...people,..p}
       })
    })

Ну, вы также можете использовать карту, чтобы получить ответ с полными элементами

people = [{id: 1, name: null}, {id:2, name: null}];
forkJoin(this.people.map(p=>this.api.getName(p.id))).pipe(
   map((res:any[])=>{
       const result=this.people.map((p,index)=>
         //if the response is an object map to
         //({...p,...res[index]})
         //if the response is a string,
         ({...p,name:res[index]}) 
       )
       return result
    })
).subscribe(res=>{console.log(res)})
...