validator with bindInstanceFields

The doc says that if we want to use .withValidation it must be between .forField(nameField) and .bind(property).

But if i want to bind all Fields of a form with bindInstanceFields

// create the binder with reflection of the properties of person.
Binder<Person> binder = new Binder<>(Person.class);

// A FormLayout with two textField (name and age).
CustomForm form = new CustomForm();

// bind fields form with the properties person
binder.bindInstanceFields(form);

Why can now add a validator for the field name ?

binder.forField(form.getName()) .withValidator( e -> e.length() > 4, "name must have at least five characters" ); Nothing happen if i put a name with 2 character. In this case when does it happen the validation? Shouldn’t be automatic when the user write the name the person.

Can you show the entire code? for example, give us a Github link?
Few checkpoints:

  1. To use the bindInstanceFields, the field name in the layout and the property name in Bean should match, otherwise, you have to use @PropertyId annotation.
  2. Did you call binder.readBean() or binder.setBean()?
  3. Also, it would be very helpful to let us know which version of Vaadin you are using.

This is my Github link

https://github.com/jdelgadot/vaadin-test/tree/master/datamodel

It is a simple form with two textField (name and age). I bind it with a Person bean with the same properties (name and age)
In the project there are two components.

component1 - bind by fields, addind validator for name and converter for age.
component2 - bindInstaceFields and after register the validator and converter.

Component1 works fine
Component2 compile but when i raun in the application server (wildfly11) launch an error. It complains …

Caused by: java.lang.IllegalStateException: Property type ‘java.lang.Integer’ doesn’t match the field type ‘java.lang.String’. Binding should be configured manually using converter.

It seems that the converter doesn’t work.

With componet1 i see automatic validation without read or set method.

Found that you were using binder a bit wrong.
After add validator or converter, you should call bind().
for example

binder.forField(form.getAge()) .withConverter( new StringToIntegerConverter("Age must be a number") ).bind(Person::getAge, Person::setAge); notice the .bind(Person::getAge, Person::setAge) at the end.

Same for the name, after you do the binding, the validation will work.

the bindInstanceFields should be called after the two bindings. but in this case, since you only have two fields, and both have some specific handing, so you don’t need bindInstanceFields at all.

You don’t understand me.
I wondered about the use of bindInstanceField with validators and converser.

In my original question i wrote about the withvalidator is between .forField(property) and .bind(—)

In my project, the component2 is an attempt to do the same that component1 but using bindInstanceFields.

Anyway thanks for your time!!!

Unfortunately bindInstanceFields does not allow to specify validators/convertors. The only way to have validators/convertors is to call .forField(property).withValidator(…).bind() for all fields that need validator/converter, then call bindInstanceFields() to bind the rest of the fields which do not require validators/converters.

OK, Thanks a lot.

Note that if you’re going to use bindInstanceFields(), you can use forMemberField() instead of forField() to avoid having to call bind() explicitly. This is more convenient.