javaandroidrx-android

passing null in onNext through PublishSubject and filtering that response in RxJava


I have a code like this:

  getLocationObservable() //this observable returns via PublishSubject the location
          .filter(location -> {
              .....
              Here I want to be able to get a null value for the location
          })
         .flatMap(location -> anotherObservable()
                             .subscribeOn(Schedulers.io())
                             .observeOn(AndroidSchedulers.mainThread()))
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe( new Observer<........

In the Location class is it like this :

 private PublishSubject<Location> locationPublishSubject = PublishSubject.create();

    public Observable<Location> getLocationObservable() {
        return locationPublishSubject;
    }

    and then...
    locationPublishSubject.onNext( foundLocation);

now, the getLocationObservable is based on a PublishSubject, that returns the Location via onNext. and then I analyze it inside the filter operator. However, sometimes the Location is not found, and it passes null. But passing null in onNext results in a crash. More specifically, I get : UndeliverableException: java.lang.Throwable How can that be solved?


Solution

  • Rx do not work with null eventually throwing an exception. You can use here a Wrapper pattern.

    Example in Kotlin

    class Wrapper<T>(val value: T?)
    

    Modify your subject to emit location wrapped in the wrapper class. In the filtering option check if it contains null or not, like

    .filter{ it.value != null }
    

    Example in Java

    Add class Wrapper

    public class Wrapper<T> {
        public final T value;
    
        public Wrapper(T value) {
             this.value = value;
        } 
    }
    

    Then use it when emitting new location and filtering it.

    public Observable<Location> getLocationObservable() {
            return locationPublishSubject;
    }
    and then...
    locationPublishSubject.onNext(new Wrapper(foundLocation));
    
    .filter(wrapper -> {
        wrapper.value != null;
    })
    

    Alternatively you can skip emitting location if it is null, if it's possible.