I have created a Rx.Observable
from a stream of events:
Rx.Observable.fromEvent(recognizeStream, 'data')
In which every data event looks like this:
{ error: null, alternatives: [result1, result2, result3] }
I want to pluck every value inside the array of alternatives
and merge those into the stream. What operators do I have to look at?
As far as I know the flatMap
and concatMap
could do the job but I don't get the idea from their example.
Can somebody explain which operator i should use and provide me with an example?
An observable produces values over time. An array is created as a static set of values. In a sense, observables are asynchronous where arrays are synchronous.
The FlatMap operator transforms an Observable by applying a function that you specify to each item emitted by the source Observable, where that function returns an Observable that itself emits items. FlatMap then merges the emissions of these resulting Observables, emitting these merged results as its own sequence.
take returns an Observable that emits only the first count values emitted by the source Observable. If the source emits fewer than count values then all of its values are emitted. After that, it completes, regardless if the source completes.
The family of xxxMap()
operators all deal with higher-order Observables. Which means they allow you to create Observables inside the main Observable and inline the resulting values into the primary stream. So you could read the type signature as Observable<Observable<T>> => Observable<T>
Given a stream which every emission x is an Observable containing 4 value emissions:
input: --x----------x
flatMap a-a-a-a-| b-b-b-b-|
result: --a-a-a-a----b-b-b-b-|
The xxxMap()
operators all work with results of type Observable
, Promise
or Array
. Depending on what you put into it will get converted to Observable if needed.
Rx.Observable.of('')
.flatMap(() => [1,2,3,4])
.subscribe(val => console.log('array value: ' + val));
Rx.Observable.of('')
.flatMap(() => Promise.resolve(1))
.subscribe(val => console.log('promise value: ' + val));
Rx.Observable.of('')
.flatMap(() => Promise.resolve([1,2,3,4]))
.subscribe(val => console.log('promise array value: ' + val));
Rx.Observable.of('')
.flatMap(() => Rx.Observable.from([1,2,3,4]))
.subscribe(val => console.log('Observable value: ' + val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js"></script>
In your case you can easily flatMap the objects and return the arrays:
Rx.Observable.of({ error: null, alternatives: ['result1', 'result2', 'result3'] })
.flatMap(val => val.alternatives)
.subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js"></script>
flatMap
, better known as mergeMap
will merge
all emissions whenever they come into the main stream.
concatMap will wait for all emissions to complete before concat
the next stream:
but switchMap will abandon the previous stream when a new emission is available and switch to emit values from the new stream:
You should pluck "alternatives" then to iterate over the array use from, as from creates a new observable you need to flatten up it, so use you need flatMap to do the job. So finally you have alternatives back into the stream.
try it:
var data = {
error: null,
alternatives: [{
result: 1
}, {
result: 2
}, {
result: 3
}]
}
var input$ = Rx.Observable.of(data);
input$.pluck('alternatives').flatMap(alternatives => Rx.Observable.from(alternatives)).subscribe(alternative => console.log(alternative));
<script src="https://npmcdn.com/@reactivex/[email protected]/dist/global/Rx.umd.js"></script>
Operators flatMap()
and concatMap()
are both a good choice. You can just turn the alternatives
property to another Observable and then emit the array items merged into the stream.
const Observable = Rx.Observable;
Observable.of({ error: null, alternatives: ['result1', 'result2', 'result3'] })
.concatMap(val => {
return Observable.from(val['alternatives']);
})
.subscribe(val => console.log(val));
This prints to console:
result1
result2
result3
See live demo: https://jsbin.com/foqutab/2/edit?js,console
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With