I'm quite new to FRP and decided to get started with Bond and ReactiveKit as it seemed lightweight enough to start gradually applying it to my apps and my head.
I have a setup where I have a view, which has an observable State
and I have a view model with another observable property of type State
. I want my view to be dull and unaware of the semantics, so I want my view model to validate the state, transform it and send back to the view.
The view contains a couple of text fields and a segmented control. When the segmented control is 0
, I want only the first text field to be visible, otherwise — both fields. Whenever the user enters something or taps the segmented control, the observable state object is updated. Here is the State
struct:
enum ValueType {
case text
case number
}
struct State {
var name: String?
var unit: String?
var valueType: ValueType = .text
var showsUnitTextField: Bool = true
}
Here is the best I could come up with:
View model:
override init() {
super.init()
self.bind()
}
let inputState: Observable<State> = Observable<State>(State())
var outputState: Observable<State> = Observable<State>(State())
private func bind() {
inputState.map(self.sanitizeState(_:)).bind(to: outputState)
}
private func sanitizeState(_ state: State) -> State {
var newState = state
newState.showsUnitTextField = state.valueType == .number
return newState
}
View controller:
private func bind() {
myView.reactive.state.bind(to: viewModel.inputState)
viewModel.outputState.bind(to: myView.reactive.state)
}
Basically I'm having two observables, one receives the updates and the other one sends the transformed value back to the view. This solutions seems to introduce a heavy boilerplate and I'm looking for a better one. Does anyone have any idea?
P.S. Other scenarios where this could come handy is when I want to have some constraints on the user input (only letters or only digits), or maybe I want to format the input in a fancy way.