Recently somebody asked me how he can send a default value if the stream hasn’t sent a new value in 5 minutes using RxSwift.
The final solution is short, however it uses few operators like
flatMapLatest together which makes it more … advanced usage of Rx.
I thought it would be a great case-study for an article. So here it is! Enjoy reading 📚💪
So… ones again… Imagine you have an Observable which constantly sends events from time to time. However, if the delay between 2 next events is too big you want to send a default value.
To create a countdown you can use the
interval operator. This is easy:
Now you need to combine the timer with the original Observable. What’s more, you need to invalidate the old timer and run a new one if the original Observable sends an event.
flatMapLatest is the operator which we are looking for:
of, just & concat – Not too many? 😱
flatMap transforms the Observable by sending events from inner Observable as an output. If you had return only the
defaultValueIfIdle inside the
flatMapLatest you would lose the event emitted by
concat allows you to connect multiple Observables into a single one. It subscribes to Observables when previous Observable sends
complete. In our case
flapMapLatest sends the
item (from .
just()) and then it starts the timer.
Observable.justis the easiest why to create an Observable with single value. It sends the given value as
nextevent always followed by
completed. You can read more about
justoperator in this article.
Since you use the
flapMapLatest not just the
flatMap, it will timer will invalidate the timer if an event comes before the countdown finish 🙌 🎉.
Countdown before first event
Right now the countdown starts after the first event from
originalObservable. It would be nice to have the countdown also earlier:
You can just listen for the timer and invalidate it with
originalObservable sends the first event.
After all, you need to take care of one thing more. Right now you have 2 different subscriptions of
originalObservable. You use it as a parameter of
takeUntil and also
observableWithDefaultValue derives from it.
It would be nice to share events between these two subscriptions. You can just use
flatMapLatest is a powerful operator which can be used to invalidate previous Observables. What’s more, you can use it in a combination of
merge) to create custom sequences.
If you liked the article, don’t forget to share it on Twitter or on other social media 😉