0

Here is short snippet of code:

    val subject = BehaviorSubject.createDefault(emptyList<Int>())
    subject.onNext(Arrays.asList(1, 2, 3))
    subject.flatMapIterable { list: List<Int> -> list }
            .subscribeBy(
                    onNext = { l("on next", it) },
                    onComplete = { l("on complete") }
            )

Why onComplete doesn't not call here? What I should do for working this code? Because in original code I can not use .toList() method.

Ivan Sadovyi
  • 168
  • 1
  • 15
  • Why are you using a `BehaviorSubject`? You have to call `onComplete()` on it explicitly. – akarnokd Oct 05 '17 at 15:50
  • 1
    Why would `onComplete` be called here? Your subject isn't done emitting items yet - you could still call `onNext` on it with items. – zsmb13 Oct 05 '17 at 15:54
  • @zsmb13 So calling of onCompete is same as in subject? I thought it will redefined by observable in flatMapIterable. – Ivan Sadovyi Oct 05 '17 at 16:09
  • `flatMapIterable` will only emit events based on the ones that it itself receives. In the case of `onComplete`, it will complete right when whatever it's chained to completes. – zsmb13 Oct 05 '17 at 17:28
  • @zsmb13 thanks for the answer. I tried call `onComplete` method on subject, but `onNext` was not called, only `onComplete` of subscriber. How I can work it as I expeceted, i.e. flatMap iterable with calling `onNext` and `onComplete` of subscriber? – Ivan Sadovyi Oct 05 '17 at 19:59

1 Answers1

3

The BehaviorSubject you have in its form is an infinite source unless onComplete is called on it. Therefore flatMapIterable will not complete and your onComplete handler will never get invoked.

So either you complete the BehaviorSubject:

val subject = BehaviorSubject.createDefault(emptyList<Int>())
subject.onNext(Arrays.asList(1, 2, 3))
subject.flatMapIterable { list: List<Int> -> list }
       .subscribeBy(
                onNext = { l("on next", it) },
                onComplete = { l("on complete") }
       )

subject.onComplete() // <-----------------------------------------------------

or you take at most one item of it

val subject = BehaviorSubject.createDefault(emptyList<Int>())
subject.onNext(Arrays.asList(1, 2, 3))
subject.take(1) // <----------------------------------------------------------
       .flatMapIterable { list: List<Int> -> list }
       .subscribeBy(
                onNext = { l("on next", it) },
                onComplete = { l("on complete") }
       )
akarnokd
  • 69,132
  • 14
  • 157
  • 192