angular rxjs rxjs5

angular - La mejor manera de “aplanar” una matriz dentro de un RxJS Observable



rxjs pipe (4)

Angular de 6 notas.

Si está utilizando como operador pipeable, do se conoce como tap!

https://www.learnrxjs.io/operators/utility/do.html Aquí hay un ejemplo.

// RxJS import { tap, map, of, mergeMap} from ''rxjs/operators''; backendSource .pipe( tap(items => console.log(items)), mergeMap(item => item ), map(item => console.log(item.property)) );

El backend con frecuencia devuelve datos como una matriz dentro de un RxJS 5 Observable (estoy usando Angular 2).

A menudo me encuentro con ganas de procesar los elementos de la matriz individualmente con los operadores RxJS y lo hago con el siguiente código ( JSBin ):

const dataFromBackend = Rx.Observable.of([ { name: ''item1'', active: true }, { name: ''item2'', active: false }, { name: ''item3'', active: true } ]); dataFromBackend // At this point, the obs emits a SINGLE array of items .do(items => console.log(items)) // I flatten the array so that the obs emits each item INDIVIDUALLY .mergeMap(val => val) // At this point, the obs emits each item individually .do(item => console.log(item)) // I can keep transforming each item using RxJS operators. // Most likely, I will project the item into another obs with mergeMap() .map(item => item.name) // When I''m done transforming the items, I gather them in a single array again .toArray() .subscribe();

La línea mergeMap(val => val) no se siente muy idiomática.

¿Existe una mejor manera de aplicar transformaciones a los miembros de una matriz que emite un observable?

NÓTESE BIEN. Quiero que los operadores RxJS (métodos de matriz vs) transformen mis elementos porque necesito la capacidad de proyectar cada elemento en un segundo observable. Caso de uso típico: el backend devuelve la lista de identificadores de elementos y debo solicitar todos estos elementos al backend.


En realidad, si lo necesitas dentro de la corriente solo usa esto:

.flatMap(items => of(...items))


Puede usar concatAll() o mergeAll() sin ningún parámetro.

dataFromBackend .do(items => console.log(items)) .mergeAll() // or .concatAll()

Esto (incluido mergeMap ) funciona solo en RxJS 5 porque trata los Observables, los arreglos, los objetos de tipo array, las Promesas, etc. de la misma manera.

Eventualmente podrías hacer también:

.mergeMap(val => Observable.from(val) .do(item => console.log(item)) .map(item => item.name) ) .toArray()


Si se trata de una operación sincrónica, sugeriría utilizar Array.map de javascript en Array.map lugar, incluso debería ahorrarle algo de rendimiento:

const dataFromBackend = Rx.Observable.of([ { name: ''item1'', active: true }, { name: ''item2'', active: false }, { name: ''item3'', active: true } ]); dataFromBackend .map(items => items.map(item => item.name)) .subscribe();