softwaremill/quicklens

Possible to seperate path from modify call?

zlangbert opened this issue · 6 comments

I'm using quicklens in scalajs-react and I'd like to write a function like this:

// updates component state
def update(path: State => String)(e: ReactEventI): Unit = {
  val v = e.target.value
  $.modState(modify(_: State)(path).setTo(v))
}

// renders component
def render(): ReactElement = {
  TextField(
    onClick: ReactEvent => Unit = update(_.field) _
  ),
  TextField(
    onClick: ReactEvent => Unit = update(_.field2) _
  )
}

This fails with

Path must have shape: _.field1.field2.each.field3.(...), got: f

Is this possible? Thanks

I can define it like this

def update[T](f: State => PathModify[State, String])(e: ReactEventI): Unit = {
  val v = e.target.value
  $ modState (path(_).setTo(v))
}

update(modify(_: State)(_.field)) _

It would be nice to be able to drop that boilerplate though

I dont understand what you are wanting. Quicklens is about updating immutable case-class structures, I can't see any of that in your example, it has Unit return type...?

@benhutchison This is in a React app. State is a case class and modState is State => State

adamw commented

It is possible by writing a custom macro - I don't think quicklens can help here. What's your exact use-case - where do you need to use update(_.field) _? Maybe knowing the broader context it will be possible to come up with sth simple than a macro.

@adamw I updated my the initial comment with a more complete example. I think this is a pretty rare use case and the workaround isn't bad. If there is no simple fix it's probably not worth it.

adamw commented

I think for a React app it definitely makes sense - but that would be a separate React library.
I've done in fact a similar thing for Supler (http://docs.supler.io/en/latest/backend/formdef/basics.html), also using a macro.
I'll close this as I'm afraid quicklens can't help here.