I am trying to write a Vaadin app in Kotlin. To bind data, Vaadin 8 now provides the ability to bind data of type safe. In Kotlin, I would expect such work:
class LoginModel { var username: String = "" var password: String = "" } class LoginView : FormLayout() { val name = TextField("name") val password = TextField("password") val loginButton = Button("login") init { val binder = Binder<LoginModel>() binder.forField(name).bind( { it.username }, { bean, value -> bean.username = value })
I get the following error message here:
Error:(23, 31) Kotlin: Type inference failed: Not enough information to infer parameter BEAN in fun <BEAN : Any!, TARGET : Any!, BEAN : Any!> Binder.BindingBuilder<BEAN#1 (type parameter of bind), TARGET>.bind(p0: ((BEAN#1!) -> TARGET!)!, p1: ((BEAN#1!, TARGET!) -> Unit)!): Binder.Binding<BEAN#1!, TARGET!>! Please specify it explicitly.
I tried to explicitly specify type parameters:
binder.forField(name).bind<LoginView, String, LoginView>( { it.username }, { bean, value -> bean.username = value })
but this leads to an error message (and other sytax errors, so I did not follow this approach)
Error:(23, 35) Kotlin: No type arguments expected for fun bind(p0: ValueProvider<LoginModel!, String!>!, p1: Setter<LoginModel!, String!>!): Binder.Binding<LoginModel!, String!>! defined in com.vaadin.data.Binder.BindingBuilder
My second approach was to pass property attributes of Kotlin directly, but the error message was the same as the first:
binder.forField(name).bind(LoginModel::username.getter, LoginModel::username.setter)
The last request tried to use the extension method and make everything as explicit as possible:
fun <BEAN, TARGET> Binder.BindingBuilder<BEAN, TARGET>.bind(property: KMutableProperty1<BEAN, TARGET>) { fun set(bean: BEAN): TARGET = property.get(bean) fun get(bean: BEAN, value: TARGET): Unit = property.set(bean, value) this.bind(::set, ::get) }
But this leads to the same error message as the first