What is the purpose of doOnNext(...) in RxJava
IMPORTANT EDIT: -in bold characters immediately below-
* Once one grasps the concept,
I warmly suggest you to have a look at this link, is a lifechanger, not only because we use different observable as Observable
, Single
, Maybe
that could be need a different tool as doOnEvent()
for Single
and doOnEach()
for Observable
but because if you want to debug, there are some reasons why doOnNext() could often even not be the ideal choice, because we could ignore other events that are relevant to resolve the problem*
ORIGINAL REPLY: -partially modified-
First of all doOnNext()
can be called even more times in the chain of operators between Observable and Subscribe, this gives to you greater possibilities to debug your code. Because of its "stream" nature, is not easy to do debugging in RXJava, doOnNext()
instead makes debugging easier. At this purpose you may consider also to combine it with thedoOnError()
operator. Why not using a simple onNext()
? Because debugging is not strictly related to the logic of the code, in theory you could also eliminate the doOnNext()
before to go in production.
A really essential thing to understand is that given an Observable to subscribe long chain, you can use the doOnNext in a particular point, to see what an operator is giving back to another one:
For instance :
Observable.just("Donald", "Duck", "Mickey", "Goofy",
"Uncle")
.doOnNext{System.out.println("Here ou will get the strings above:$it ")}
.map{it.length}
.subscribe { println("Here you will get the numbers of how every string is long: $it") }}
A typical use case to employ doOnNext()
could for example occur when you want to cache a response from a server, so for instance you could use map()
but also doOnNext()
, because it allows you to make your code more readable as instead you would put a simple onNext()
that ideally could have been structured to follow other instructions. (This is arguable, as all the architectural thoughts)
Equally to doOnNext()
and for the same debugging purposes
you could use others self-explanatory operators:
doOnSubscribe(), doOnUnsubscribe(), doOnCompleted(), doOnError(), doOnTerminate(),finallyDo(), doOnEach(), doOnRequest()
doOnNext()
allow you to see what is going on into the Observable (often really long) chains, what is really important is that you can kinda spying what is going on trough the chain, without affecting any operation, without making any transformation( let's say not properly a kind of Log.d
we use in imperative, not reactive code). This is is the reason why is called a side effect.
EDIT(because of the question in the comments):
doOnNext()
and the method above are just callbacks, please refer to that, doOnNext()
as the official documentation says
just modifies an Observable so that it invokes an action when it calls onNext.
Really simple, this is why is called sometimes to upload the progress bar, but also is really used in the repository pattern, for instance if you want to store data to the db/or caching after a call to retrofit for instance.
If you are really curious under the hood the doSomethingReactive methods just call the method call()
( a callback from the Interface Action) inside the "real" method SomethingReactive
doOnNext
is for side-effects: you want to react (eg. log) to item emissions in an intermediate step of your stream, for example before the stream is filtered, for transverse behavior like logging, but you still want the value to propagate down the stream.
onNext
is more final, it consumes the value.