0

I am making two ways binding for UITextField extension. It works well with string. But why not Int? This is my extension:

import Foundation
import RxCocoa
import RxSwift

extension UITextField {
    func bind(with property: BehaviorRelay<String?>, bag: DisposeBag = DisposeBag()) {
        property.bind(to: self.rx.text).disposed(by: bag)
        self.rx.text.bind(to: property).disposed(by: bag)
    }

    func bind(with property: BehaviorRelay<Int?>, bag: DisposeBag = DisposeBag()) {
        property.map { intValue in
            return Int.toString(intValue) //convert from Int to String
        }.bind(to: self.rx.text).disposed(by: bag)
        self.rx.text.orEmpty.map { text in
            return String.toInt(text) ?? 0 //convert from String to Int
        }.bind(to: property).disposed(by: bag)
    }
}

In my viewModel:

let fullName = BehaviorRelay<String?>(value: nil)
let phone = BehaviorRelay<Int?>(value: nil)

Usage:

textField1.bind(with: viewModel.fullName) //working well
textField2.bind(with: viewModel.phone) //only from viewModel to textField

But when I use directly it working like this:

textField2.rx.text.map { text in
    return String.toInt(text) ?? 0
}.bind(to: viewModel.phone).disposed(by: bag)

Am I missing something? Any answer are appeciated. Thanks.

Ho Si Tuan
  • 520
  • 3
  • 13
  • 1
    Works both ways for me. Can you describe the exact steps to reproduce the problem, and what exactly happens? – Sweeper Aug 03 '21 at 04:14
  • I have viewModel get data from API. In my case, after loading data, it show value in the textfield, but when I change text, value in viewModel keep stable – Ho Si Tuan Aug 03 '21 at 04:17
  • But, when I use it directly. It working. ``` textField2.rx.text.map { text in return String.toInt(text) ?? 0 }.bind(to: viewModel.phone).disposed(by: bag)``` – Ho Si Tuan Aug 03 '21 at 04:27

1 Answers1

0

I missing pass bag when I call the function. Exactly, it should be:

let bag = DisposeBag()
textField1.bind(with: viewModel.fullName, bag: bag) //working well
textField2.bind(with: viewModel.phone, bag: bag)

Also I need to remove default value for avoiding forgetting in the future

func bind(with property: BehaviorRelay<Int?>, bag: DisposeBag) {
        property.map { intValue in
            return Int.toString(intValue) //convert from Int to String
        }.bind(to: self.rx.text).disposed(by: bag)
        self.rx.text.orEmpty.map { text in
            return String.toInt(text) ?? 0 //convert from String to Int
        }.bind(to: property).disposed(by: bag)
    }
Ho Si Tuan
  • 520
  • 3
  • 13