Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava : fromIterable is not emitting all the items

I was trying out a simple code with fromIterable and flatMap operators. I'm just mapping a stream of long values to a stream of Result in my code. Nothing else

Here's my code. I have an empty class

    class Result {
        @Override
        public String toString() {
            return "result";
        }
    }

And a function

    public Observable<Result> getResults(List<Long> requests) {
        return Observable.fromIterable(requests)
                .flatMap( aLong -> {
                    Result[] items = {new Result(), new Result()};
                    return Observable.fromIterable(Arrays.asList(items));
                });
    }       

And I subscribe to this as follows

     List<Long> ids = new ArrayList<>(Arrays.asList(1L, 2L, 3L));

     getResults(ids)
    .subscribe(new DisposableObserver<Result>() {
        @Override
        public void onNext(Result item) {
            Log.d(TAG, "onNext: " + item);
        }

        @Override
        public void onComplete() {
            Log.d(TAG, "onCompleted: ");
        }

        @Override
        public void onError(Throwable e) {
            Log.e(TAG, "onError: " + e.getMessage());
        }
    });     

My expected output is

    LOG: onNext: result
    LOG: onNext: result
    LOG: onNext: result
    LOG: onNext: result
    LOG: onNext: result
    LOG: onNext: result
    LOG: onCompleted:         

For each emission of fromIterable , the flatMap expected to return a stream with 2 values, so total 6 times onNext and then onComplete

But what I'm getting is

    LOG: onNext: result
    LOG: onNext: result
    LOG: onCompleted:        

Only 2 times onNext is triggering and then it completes. Where did the remaining 4 values go?

But the strange thing is , I added a Log to the doOnNext of fromIterable in my getResults function as follows

    public Observable<Result> getResults(List<Long> requests) {
        return Observable.fromIterable(requests)
                .doOnNext(i -> Log.d(TAG, "fromIterable emitted " + i))
                .flatMap(aLong -> {
                    Result[] items = {new Result(), new Result()};
                    return Observable.fromIterable(Arrays.asList(items));
                });
    }

Now it is emitting all the values!!!! Here's the output

    LOG: fromIterable emitted 1
    LOG: onNext: result
    LOG: onNext: result
    LOG: fromIterable emitted 2
    LOG: onNext: result
    LOG: onNext: result
    LOG: fromIterable emitted 3
    LOG: onNext: result
    LOG: onNext: result
    LOG: onCompleted: 

Whats happenning here? What change did the onNext make to the chain to emit all the values?

like image 246
doe Avatar asked Aug 09 '26 13:08

doe


1 Answers

as explained by @akarnokd, you are logging similar text within very short amount. Logging should be unique in your case,

List<Long> ids = new ArrayList<>(Arrays.asList(1L, 2L, 3L));

    getResults(ids)
            .subscribe(new DisposableObserver<Result>() {
                @Override
                public void onNext(Object item) {
                    Log.d(TAG, "onNext: called at " + System.currentTimeMillis());
                }

                @Override
                public void onComplete() {
                    Log.d(TAG, "onCompleted: ");
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "onError: " + e.getMessage());
                }
            });

or mention in your observable similarly

  ...
  .doOnNext(i -> Log.d(TAG, "fromIterable emitted " + i))
  ...
like image 188
Aks4125 Avatar answered Aug 12 '26 08:08

Aks4125



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!