Sebastian Krogull February 2016

RxSwift: Zip Observables only if requirements are met

Imagine a user profile which allows editing of fields like name, surname, age and avatarImage. When the user clicks Save, requests are sent for each value that has been changed.

Now please think of functions with signatures like those:

func rx_updateUserName(name: String) -> Observable<UpdateUserNameResponse>
func rx_updateSurname(surname: String) -> Observable<UpdateSurnameResponse>
func rx_updateAge(age: Int) -> Observable<UpdateAgeResponse>

Normally we would just zip those requests like this:

let nameReqObservable = rx_updateUserName("Gandalf")
let surnameReqObservable = rx_updateSurname("The White")
let ageReqObservable = rx_updateAge(123)

let zippedRequests = Observable.zip(nameReqObservable, surnameReqObservable, ageReqObservable, 
    resultSelector: { (userNameResponse, surnameResponse, areResponse) in

    return (userNameResponse, surnameResponse, areResponse)
}).subscribeNext(...)

What should I do when I only want to perform the requests for the values that changed?

Answers


Son Nguyen March 2016

Have you tried .combineLatest()? Visualization here - http://rxmarbles.com/#combineLatest In your case, whenever there is a value changed in one of the input observables, the combinedRequests observable will emit a new set of inputs.

let combinedRequests = Observable.combineLatest(nameReqObservable, surnameReqObservable, ageReqObservable, 
    resultSelector: { (userNameResponse, surnameResponse, ageResponse) in

    return (userNameResponse, surnameResponse, ageResponse)
}).subscribeNext(...)

Doc from RxSwift, .combineLatest():

Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element.

Post Status

Asked in February 2016
Viewed 2,689 times
Voted 6
Answered 1 times

Search




Leave an answer