Observable with array of Strings from TextFields

Hi again (;

I do some fun for myself with RxSwift and I encountered the problem: How to create one Observable with array of Strings from 3 TextFields. I resolved it like in the code below, but it looks messy. Is any way to do it cleaner?

lazy var textFieldsOutput: Observable<[String]> = { [unowned self] in
    return Observable<[String]>.create({ (observer) -> Disposable in
        var texts: [String] = self.textFields.map { $0.text ?? "" }
        for (i, textField) in self.textFields.enumerated() {
            self.textFields[i].rx.text
                .skip(1)
                .subscribe(onNext: { text in
                    texts[i] = text ?? ""
                    observer.onNext(texts)
                }).addDisposableTo(self.bag)
        }
        return Disposables.create()
    })
}()

Hi, what you need is combineLatest, check Chapter 9 the “Combining Elements” part :ok_hand:

1 Like

thanks (: I figured out this result.

    let one = self.textFields[0].rx.text.asObservable()
    let two = self.textFields[1].rx.text.asObservable()
    let three = self.textFields[2].rx.text.asObservable()
    return Observable.combineLatest(one, two, three) {
        return [$0, $1, $2].flatMap { $0 }
    }

much better! but maybe is some way to make it less hard typed?

self.textFields.map { $0.rx.text.asObservable() }

this code returns [Observable< String? >]. Is any easy way to convert it to Observable<[String?]> ?

yes, combineLatest also takes an array of observables (instead of a list of observables)

1 Like

Thank you Marin! :smile:

No my code looks like this if anyone wonders :wink:

  lazy var textFieldsOutput: Observable<[String]> = { [unowned self] in
    let observables = self.textFields.map { $0.rx.text.asObservable() }
    return Observable.combineLatest(observables).map{$0.flatMap{$0}}
}()

Much shorter than in first post :joy:

1 Like