Search code examples
rx-swiftrx-cocoa

combined textfields result if all are not empty RxSwift


Im trying to combine the inputs of all the textfield and check if it has an input but upon observing combine latest only subscribed once.

Is there any other way to check the textfields if they are empty using rxswift? those the OTP textfields

let otp1Value: Observable<Bool> = self.otp1.rx.controlEvent(UIControlEvents.editingDidEnd)
            .withLatestFrom(self.otp1.rx.text)
            .map{ !$0!.isEmpty }
            .share()

        let otp2Value: Observable<Bool> = self.otp1.rx.controlEvent(UIControlEvents.editingDidEnd)
            .withLatestFrom(self.otp2.rx.text)
            .map{ !$0!.isEmpty }
            .share()

        let otp3Value: Observable<Bool> = self.otp1.rx.controlEvent(UIControlEvents.editingDidEnd)
            .withLatestFrom(self.otp3.rx.text)
            .map{ !$0!.isEmpty }
            .share()

        let otp4Value: Observable<Bool> = self.otp1.rx.controlEvent(UIControlEvents.editingDidEnd)
            .withLatestFrom(self.otp4.rx.text)
            .map{ !$0!.isEmpty }
            .share()

        let otp5Value: Observable<Bool> = self.otp1.rx.controlEvent(UIControlEvents.editingDidEnd)
            .withLatestFrom(self.otp5.rx.text)
            .map{ !$0!.isEmpty }
            .share()

        let otp6Value: Observable<Bool> = self.otp1.rx.controlEvent(UIControlEvents.editingDidEnd)
            .withLatestFrom(self.otp6.rx.text)
            .map{ !$0!.isEmpty }
            .share()

        Observable.combineLatest(
            otp1Value.asObservable(),
            otp2Value.asObservable(),
            otp3Value.asObservable(),
            otp4Value.asObservable(),
            otp5Value.asObservable(),
            otp6Value.asObservable())
            .asObservable().subscribe(onNext: { [weak self] (arg: (Bool, Bool, Bool, Bool, Bool, Bool)) -> Void in

                guard let self = self else { return }

                print("args \(arg)")

                switch arg {
                case (true, true, true, true, true, true):
                    self.step2CellViewModel.otpIsValid.onNext(true)
                    print("args \(arg)")
                default:
                    self.step2CellViewModel.otpIsValid.onNext(false)
                    print("args false")
                }
            })
            .disposed(by: self.disposeBag) 

Solution

  • This should also work:

    let textFields = [otp1, otp2, otp3, otp4, otp5, otp6]
    Observable.combineLatest(textFields.map { $0!.rx.text.orEmpty })
        .map { $0.map { $0.isEmpty } }
        .map { !$0.contains(true) }
        .bind(to: step2CellViewModel.otpIsValid)
        .disposed(by: disposeBag)