Background
I'm using a java web UI library (Vaadin, but that's irrelevant - I'm not using the Scaladin add-on) which has a TextField
that has a method setValue(String)
to set the current text value.
As it's a java library, it has no notion of Option
but can represent a null
value as e.g. an empty string (it's configurable). So I've written an implicit wrapper class as follows:
implicit class ExtendedTextField(self: TextField) {
def :=(value: String) = self.setValue(value)
def :=(maybeValue: Option[String]) = self.setValue(maybeValue.orNull)
}
This allows me to set the value using the :=
operator directly on a TextField instance and allows me to deal with the Option to null conversion in a single place.
Problem
When I have e.g. a form with a bunch of text fields showing the values for some object of type X, then if I have an Option[X] I'm doing this:
fieldA := (for (x <- maybeX) yield x.valueA)
fieldB := (for (x <- maybeX) yield x.valueB)
fieldC := (for (x <- maybeX) yield x.valueC)
...
In other words, I want to call the :=
with Some(string) in case I have maybeX is Some but with None if maybeX is none. In addition, suppose x.valueD is actually an Option[String], I would call
fieldD := (for (x <- maybeX) yield x.valueD).flatten
(I could simply always call flatten
, but it wouldn't have an effect if there are no nested options)
Is there a nicer way to write this, getting rid of all the duplicate for comprehensions and flattening the result? Maybe using a macro?
I'd prefer not to use reflection (I'm sure it will be possible to put all the fields in a sequence, zip it with a sequence containing the property names, then map this using a function that returns None or does the relflection lookup, and also flattens the result).