Как извлечь данные из Rx JS наблюдаемых - PullRequest
0 голосов
/ 02 мая 2020

Я недавно изучил Angular и пытаюсь лучше понять Rx JS. Предположим, у меня есть ответ API от HttpClient.get, который дает мне Observable следующего JS объекта:

const response = {
  photos: [
    {
      id: 1,
      src: '1.jpg',
    },
    {
      id: 2,
      src: '2.jpg',
    },
    {
      id: 3,
      src: '3.jpg',
    }
  ]
}

Конечный результат, который я ищу: ['1.jpg', '2.jpg', '3.jpg']

Я могу сделать следующее, чтобы получить каждого отдельного человека c по одному:

const source = from(response.photos);
const images = source.pipe(
    pluck('src')
);
images.subscribe({
    next(x) { 
        console.log(x); // results in: 1.jpg 2.jpg 3.jpg, one item per line.
    }
});

Но то, что я хотел бы сделать, и что я думал, будет работать, это создать можно наблюдать за полным ответом (как это было бы дано из вызова Angular в http.get ()) и возвращать все свойства sr c в виде массива, например:

const source = of(response);
const images = source.pipe(
    pluck('photos'),  // i expect this to be [{ id: 1, src: '1.jpg' }, ... ]
    map(x => x.src),  // i expect x to to be { id: 1, src: '1.jpg' } (but it is not)
);
images.subscribe({
    next(x) { 
        console.log(x); // i expect x to be the result of the map call earlier, i.e. ['1.jpg', '2.jpg', '3.jpg']
    }
});

Полагаю, Вероятно, я зациклился на ожидании окончательного значения в сравнении со значениями по мере их поступления или чего-то в этом роде. Если кто-то может помочь объяснить, как получить желаемый результат или предложить другой / лучший подход, я надеюсь, что что-то щелкнет, и вещи начнут приобретать больше смысла.

Ответы [ 3 ]

2 голосов
/ 02 мая 2020

Поскольку после получения результата источника без каких-либо манипуляций с событиями вам нужно лишь немного манипулировать данными, я просто хочу использовать карту, подобную этой:

const source = of(response);
const images = source.pipe(map(data => data.photos.map(x => x.src)));
images.subscribe(console.log);
0 голосов
/ 02 мая 2020

Здесь я заменил ваш клиентский вызов методом getImages(). В дополнение к этому всегда следите за отменой подписи наблюдаемых в методе ngDestroy, чтобы предотвратить утечку памяти


let images;
let imageSrc;

getImages(): Observable<any> { 
 return this.httpClient.get(url);
}

this.getImages().pipe().subscribe(response => 
{ 
  this.images = response.photos;
  this.imageSrc = response.map(x => x.src)
});

0 голосов
/ 02 мая 2020

Учитывая ваш второй подход, у вас есть ошибка в операторе map. По сути, вы передаете массив наблюдаемой, и в операторе map ожидается, что результатом будет массив, а не объект, подобный тому, который вы там обрабатываете.

Правильный код следующий:

const source = of(response);
    const images = source.pipe(
      pluck("photos"),
      // here map over the output which is an array
      map(x => x.map(y => y.src))
    );
    images.subscribe({
      next(x) {
        console.log(x); // the result is: ['1.jpg', '2.jpg', '3.jpg']
      }
    });
...