0

I'm having an issue with onNext not getting called when using the RxJava toList operator. Everything works exactly as I expect up until the toList gets called. Things I've read here, here and here seem to indicate the issue with onCompleted not being called but I'm still new to RxJava so I'm not sure where I would need to call that in order for this to work.

The most confusing thing is that the architecture I was trying to follow from Google's Android Architecture doesn't seem to call onCompleted and it works just fine.

Subscription subscription = mDataSource
        // Get Observable<List<Location>> from SQLBrite database
        .getLocations()
        // Convert to Location object
        .flatMap(new Func1<List<Location>, Observable<Location>>() {
            @Override
            public Observable<Location> call(List<Location> locations) {
                return Observable.from(locations);
            }
        })
        // Filter here
        .filter(new Func1<Location, Boolean>() {
            @Override
            public Boolean call(Location location) {
                return mPreferences.getUsesCustomLocations() || location.getId().length() <= 2;
            }
        })
        // Convert Location object to String
        .map(new Func1<Location, String>() {
            @Override
            public String call(Location location) {
                return location.getTitle();
            }
        })
        // Convert to Observable<List<String>, however using toList()
        // causes onNext() to never get called
        .toList()
        .subscribeOn(mSchedulerProvider.computation())
        .observeOn(mSchedulerProvider.ui())
        .subscribe(new Observer<List<String>>() {
            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            @Override
            public void onNext(List<String> locations) {
                processLocations(locations);
            }
        });
    mSubscriptions.add(subscription);
Community
  • 1
  • 1
apicellaj
  • 233
  • 1
  • 3
  • 16

1 Answers1

2

After calling toList() you will only get a single onNext() and that is when the source observable calls onComplete().

The reason for the behaviour that you are seeing is SQLBrite, which will send you the data every time it is changed. This means it is an unending stream so it ends up never calling onComplete().

Kiskae
  • 24,655
  • 2
  • 77
  • 74
  • Thanks for connecting the issue to SQLBrite. The Google repository I linked also uses SQLBrite and is able to call `toList` so I feel like there should be some work around. – apicellaj Oct 04 '16 at 04:39
  • @apicellaj Its not directly using SQLBrite. https://github.com/googlesamples/android-architecture/blob/todo-mvp-rxjava/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/data/source/TasksRepository.java#L105 Here they try to retrieve both remote and cached values and cut off at the first value (`.first()`) So in the example `getTasks()` returns just a single list. – Kiskae Oct 04 '16 at 08:42
  • Calling `(.first())` on my `Observable>` query from the database fixed the problem! Thanks! – apicellaj Oct 04 '16 at 15:56