Reputation: 199
I have a list of values and I going to print every element of it with Rxjava2 flowable. If there is null value, then, the program will print "it's empty value".
val datas: MutableList<String?> = arrayListOf("123",null ,"test12", "teas")
Flowable
.fromIterable(datas)
.subscribe(
object: FlowableSubscriber<String>{
override fun onComplete() {
println("on complete")
}
override fun onSubscribe(s: Subscription) {
println("on subscribe")
}
override fun onNext(t: String?) {
if(t==null){
println("it's empty value")
} else {
println("value: $t")
}
}
override fun onError(t: Throwable?) {
println("error")
t?.printStackTrace()
}
}
)
while(true){}
And I got the exception as below:
on subscribe
error
java.lang.NullPointerException: Iterator.next() returned a null value
at io.reactivex.internal.operators.flowable.FlowableFromIterable$IteratorConditionalSubscription.fastPath(FlowableFromIterable.java:311)
at io.reactivex.internal.operators.flowable.FlowableFromIterable$BaseRangeSubscription.request(FlowableFromIterable.java:122)
at io.reactivex.internal.subscribers.BasicFuseableSubscriber.request(BasicFuseableSubscriber.java:153)
at io.reactivex.internal.operators.flowable.FlowableFlatMapMaybe$FlatMapMaybeSubscriber.onSubscribe(FlowableFlatMapMaybe.java:107)
at io.reactivex.internal.subscribers.BasicFuseableSubscriber.onSubscribe(BasicFuseableSubscriber.java:67)
at io.reactivex.internal.operators.flowable.FlowableFromIterable.subscribe(FlowableFromIterable.java:66)
at io.reactivex.internal.operators.flowable.FlowableFromIterable.subscribeActual(FlowableFromIterable.java:47)
at io.reactivex.Flowable.subscribe(Flowable.java:14827)
at io.reactivex.internal.operators.flowable.FlowableFilter.subscribeActual(FlowableFilter.java:37)
at io.reactivex.Flowable.subscribe(Flowable.java:14827)
at io.reactivex.internal.operators.flowable.FlowableFlatMapMaybe.subscribeActual(FlowableFlatMapMaybe.java:54)
at io.reactivex.Flowable.subscribe(Flowable.java:14827)
at TestPlay.test4(TestPlay.kt:113)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
I'm new in reactive rxjava, and I need some expert to guide me how to handle this scenario.
I have a scenario that I need to check with database if the record is not exist then I have to save the record. But when I try deal with null value, I got the exception as I described above.
Upvotes: 1
Views: 1808
Reputation: 76
From RxJava2 documentation:
RxJava 2.x no longer accepts null values and the following will yield NullPointerException immediately or as a signal to downstream.
Solution: Before iterating list, you should make null check.
Upvotes: 4
Reputation: 610
How said @Toleubek before: RxJava doesn't support null-values, 'cause they immediately terminate your stream and call onError(...) in your Subscriber.
You can read about it here. But the mostly using solution for dealing with nulls is simple creating some wrapper-class that will be called Optional/Nullable(or something like that) with the nullable data inside. Also you can read one of the articles about working with null in RxJava on Medium.
Upvotes: 1