negative15
negative15

Reputation: 25

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) 

Upvotes: 1

Views: 1093

Answers (2)

Daniel T.
Daniel T.

Reputation: 33979

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)

Upvotes: 1

negative15
negative15

Reputation: 25

already found an answer:

 let valids: [Observable<Bool>] = [
                self.otp1, self.otp2,
                self.otp3, self.otp4,
                self.otp5, self.otp6
            ].map { field in

            field.rx.text.map({ _ in return !(field.text?.isEmpty)! })
        }

        _ = Observable.combineLatest(valids) { iterator -> Bool in
            return iterator.reduce(true, { return $0 && $1 })
        }.subscribe(onNext: { [weak self] (valid: Bool) -> Void in
            guard let self = self else { return }
            self.step2CellViewModel.otpIsValid.value = valid
        })
        .disposed(by: self.disposeBag) 

Upvotes: 0

Related Questions