2

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.

chwarr
  • 6,777
  • 1
  • 30
  • 57
Danchoys
  • 739
  • 1
  • 8
  • 14

0 Answers0