10

Let's say I have the following:

let theSubject = PublishSubject<String>()
let theObservable = Observable.just("Hello?")

How do I set the theSubject to observer theObservable?

In RxSwift we say that a subject is an observer and can subscribe to one or more Observables...

Can you show a simple code example of how I can connect theSubject as an observer of theObservable ?

pacification
  • 5,838
  • 4
  • 29
  • 51
Andrew Paul Simmons
  • 4,334
  • 3
  • 31
  • 39

2 Answers2

14

The code is:

theObservable
    .bind(to: theSubject)
    .disposed(by: bag)

or:

theObservable 
    .subscribe(theSubject)
    .disposed(by: bag)

If you only do subscribe(onNext:) as others have suggested, only the onNext events will get passed along. You should use bind to pass everything along.

(But really you probably shouldn't use a subject. Instead bind the thing(s) that are listening to the subject to the Observable directly.

Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • 1
    You need `RxCocoa` for `bind` – onmyway133 Apr 26 '19 at 11:47
  • True, you could just use `.subscribe(theSubject)` instead of `.bind(to: theSubject)`. – Daniel T. Apr 26 '19 at 12:10
  • Is there anyway to tie the cancellation / disposing to the subject? I am having to jump through these hoops because I can' create the (inner) observable until a first step completes inside a function, but need to create and return the outer subject for the function's caller to wait on. Ideally the caller could short circuit the second stage just be releasing the the subject, so there would be no audience for the inner observable. (Thanks!) – Chris Conover Oct 16 '20 at 21:06
  • I'm not sure what you are asking above. Maybe post a new question with more detail? – Daniel T. Oct 16 '20 at 21:20
8

The answer is

theObservable
    .subscribe(onNext: { theSubject.onNext($0) })
    .disposed(by: disposeBag)

This will make sure that every time that the theObservable emits, the value will be passed to theSubject too.

Note This only passes the value onNext, if you want to handle all the cases, then use bind(to:) as the answer by Daniel T. (or drive for Drivers)

Example with more Observables

In the following example values from different Observables will be passed to theSubject

let theSubject = PublishSubject<String>()
let theObservable = Observable.just("Hello?")
let anotherObservable = Observable.just("Hey there")

theSubject.asObservable()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

theObservable
    .subscribe(onNext: { theSubject.onNext($0) })
    .disposed(by: disposeBag)

anotherObservable
    .subscribe(onNext: { theSubject.onNext($0) })
    .disposed(by: disposeBag)

Output

The subject

E-Riddie
  • 14,660
  • 7
  • 52
  • 74