Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flatMap() called twice on single event

I have a ViewController in which on the init() I create a hot stream using PublishSubject. I then pass in the stream to my ViewModel using stream.asObservable() in the viewDidLoad(), as the ViewModel has other dependencies which are streams generated from the views, so it has to wait until the binding of the views is finished before creating the ViewModel. After creating the ViewModel I push an event in my ViewController into the stream and then expect the ViewModel to react to the event by firing off an asynchronous request (which has also been wrapped with Rx).

ViewController:

class ExampleViewController: ViewController {

    ....

    private let exampleStream: PublishSubject<Bool>

    init() {
        self.exampleStream = PublishSubject<Bool>()
    }

    viewDidLoad() {
        self.viewModel = viewModelFactory.create(exampleStream.asObservable())
        self.exampleStream.onNext(true)
    }

    ....
}

ViewModel:

class ExampleViewModel {

    init(stream: Observable<Bool>) {
        stream.flatMap { _ in
            doSomethingAsyncThatReturnsAnObservable()
        }
    }

    private func doSomethingAsyncThatReturnsAnObservable() -> Observable<CustomObject> { ... }
}

My problem is that doSomethingAsyncThatReturnsAnObservable() is called twice when only one event is inside the stream. I have checked that fact by using var count = 1; stream.subscribeNext { _ in print(count++) } which prints 1.

Any idea as to why subscribeNext() fires once on each event but flatMap() fires twice?

like image 285
a.ajwani Avatar asked Jan 18 '16 17:01

a.ajwani


1 Answers

This is because flatMap called on every subscription.

If you want it to be called once use shareReplay(1)

like image 136
Serg Dort Avatar answered Nov 03 '22 23:11

Serg Dort