Reputation: 8944
Let's say I have two streams.
Every time a value changes, I get that value in my value stream.
Every time I press a button, I get an event in the button stream.
I want to do something when I get an event in the buttonPresses stream, with the latest value in the values stream. e.g. Make an API call.
However, I do not want something to happen every time a value changes.
I think this is a "thinking in observables" problem. Here's the actual code I'm struggling with.
/**
* Provides a stream of POSTCODE_LOOKUP action events
* @type {Object}
*/
export let PostcodeLookupActionsStream = Actions.stream
.filter( action => action.key === KEYS.POSTCODE_LOOKUP );
/**
* Provides a stream of values from a post code input field.
* @type {Object}
*/
export let PostCodeValueStream = Actions.stream
.filter( action => action.key === KEYS.POSTCODE_CHANGE )
.map( action => action.payload.postcode )
.shareReplay(1);
// Combine the two streams....?
export let PostCodeLookupStream = Rx.Observable
.merge(PostCodeValueStream, PostcodeLookupActionsStream)
.map( (value, action) => value);
/**
* Provides a stream of address retrieved from a postcode lookup
* @type {Array}
*/
export let AddressStream = PostCodeLookupStream
.flatMapLatest( postcode => MyAPI.postcodeLookup( postcode ) )
.flatMap( response => response.json() )
.shareReplay(1);
Upvotes: 0
Views: 180
Reputation: 8944
The answer is to use withLatestFrom
. I don't know why it took me so long to find that in the docs, but it did.
/**
* Provides a stream of POSTCODE_LOOKUP events
* e.g: A stream of postcodes.
* @type {Object} a mouse event
*/
export let PostcodeLookupIntentsStream = Actions.stream
.filter( action => action.key === KEYS.POSTCODE_LOOKUP );
/**
* Provides a stream of values from a post code input field
* @type {String}
*/
export let PostCodeValueStream = Actions.stream
.filter( action => action.key === KEYS.POSTCODE_CHANGE )
.map( action => action.payload.postcode )
.shareReplay(1);
/**
* Combines `PostcodeLookupIntentsStream` and `PostCodeValueStream` to
* produce a stream of postcode values. New postcode values are emitted
* every time an event is emitted from the
* `PostcodeLookupIntentsStream`
*/
export let PostCodeLookupValueStream = PostcodeLookupIntentsStream
.withLatestFrom( PostCodeValueStream, (action, value) => value );
/**
* Provides a stream of address retrieved from a postcode lookup
* @type {Array}
*/
export let AddressStream = PostCodeLookupStream
.flatMapLatest( postcode => return MyAPI.postcodeLookup( postcode ) )
.flatMap( response => response.json() )
.shareReplay(1);
Upvotes: 1