Reset password call occurs 2 times, how can I remove the subscription in that block.
let digits = [firstDigit, secondDigit, thirdDigit, fourthDigit, fifthDigit, sixthDigit]
let digitsValid = digits.map { $0?.textField.rx.text.orEmpty.map({ $0.count == 1 }).share(replay: 1) }
let allDigitsFilled = Observable.combineLatest(digitsValid.map{ $0 ?? BehaviorRelay(value: false).asObservable()}).share(replay: 1)
allDigitsFilled.subscribe (onNext: { [weak self] (boolArray) in
guard let self = self else { return }
let isFilled = boolArray.allSatisfy({ $0 })
if isFilled {
self.viewModel.resetPassword()
}
}).disposed(by: disposeBag)
Your onNext block will be called every time any of the text fields changes its contents. Your first goal should be to make it so the block is only called when you want to reset the password.
So first, you want to put the .allSatisfy
inside an Observable.filter call so your onNext block will only be called when all six text fields contain exactly 1 character. Once you do that, then you can simply use .take(1)
which will complete the subscription once a next value is emitted.
Something like this should do it, and looks quite a bit cleaner:
let digits = [firstDigit, secondDigit, thirdDigit, fourthDigit, fifthDigit, sixthDigit]
let texts = digits.compactMap { $0?.textField.rx.text.orEmpty }
Observable.combineLatest(texts)
.filter { $0.allSatisfy { $0.count == 1 } }
.map { _ in }
.take(1)
.subscribe(onNext: { [viewModel] in
viewModel?.resetPassword()
})
.disposed(by: disposeBag)