Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxSwift - multiple Observable value within one Observable

I want to make a function like this example.

example

let num1 = Driver<Int>
let num2 = Driver<Int>
let result = Driver<String>

num1 = Observable.just(...).asDriver()
num2 = Observable.just(...).asDriver()
result = ??? // When both num1 and num2 are subscribed, this becomes a higher value among them as String.

// This type of code will be used
/* 
if $0 >= $1 {
    return "num1 = \($0)"
} else {
    return "num2 = \($1)"
}
*/

How to implement it?

like image 232
Byoth Avatar asked Jun 20 '17 06:06

Byoth


People also ask

What is Onnext in RxSwift?

Called by the Observable when it emits an item. Takes as a parameter the item emitted by the Observable. Calls are referred to as emissions .

What is observable RxSwift?

The heart of the RxSwift framework is based on observable which is also known as a sequence. Observable is the sequence of data or events which can be subscribed and can be extended by applying different Rx operators like map, filter, flatMap, etc. It can receive data asynchronously.

What is BehaviorRelay?

BehaviorRelay is a wrapper for BehaviorSubject . Unlike BehaviorSubject it can't terminate with error or completed.

How do I cancel observable RxSwift?

To explicitly cancel a subscription, call dispose() on it. After you cancel the subscription, or dispose of it, the observable in the current example will stop emitting events.


2 Answers

Don't use a Variable if you can help it. You already have a couple of observables so use them, but yes, combineLatest is the solution here:

import RxSwift

let num1 = Observable.just(3)
let num2 = Observable.just(5)
let result = Observable.combineLatest(num1, num2).map { $0 >= $1 ? "num1 = \($0)" : "num2 = \($1)" }

_ = result.subscribe(onNext: { print($0) })

The above prints "num2 = 5" when it's placed in a properly configured playground.

like image 97
Daniel T. Avatar answered Oct 25 '22 12:10

Daniel T.


You can use RxSwift Variable here instead of the Driverand to to listen on the two Observables, you can use Observable.combineLatest(..) method. Below is an example how you can achieve it:

let num1: Variable<Int>!
let num2: Variable<Int>!

let bag = DisposeBag()

num1 = Variable(1)
num2 = Variable(2)

let result = Observable.combineLatest(num1.asObservable(), num2.asObservable()) { (n1, n2) -> String in

    if n1 >= n2 {
        return "num1 = \(n1)"
    } else {
        return "num2 = \(n2)"
    }
}

result.subscribe(onNext: { (res) in
    print("Result \(res)")
}).addDisposableTo(bag)

num1.value = 5
num1.value = 8
num2.value = 10
num2.value = 7

It outputs:

Result num2 = 2
Result num1 = 5
Result num1 = 8
Result num2 = 10
Result num1 = 8
like image 42
Max Avatar answered Oct 25 '22 11:10

Max