Web Component integration with array property

Hi,

I tried to integrate a web component which will give me an array of items in result (multi select).
I created the Java class corresponding to this component and the interface model with the list of beans.
But the selected items are not synchronized from client to server.
From server to client, it works. I tried to initialize the component with selected items and they are displayed in the UI.

I’ve found a lot of issuers dealing this problem on your GitHub and they are all closed and a commit in relation with so I thought it was fixed.

I also tried the @Synchronize but nothing.

It’s my first post in your forum sorry in advance if I forgot something!

Best regards,

Hi there,

Do you own the webcomponent code? That’s probably due to the lack of notifications on array changes from the webcomponent itself.

How the selected items array is changed on the client-side?

Maybe this can help: https://www.polymer-project.org/2.0/docs/devguide/model-data


Gilberto

It’s not mine component, it’s this one : https://github.com/selvinfehric/multi-select-combo-box
I found it on https://www.webjars.org/

I’m gonna take a look at the documentation you gave me, hope it helps me!
Thanks Gilberto!

I’ve read the documentation and it seems to be OK in the webcomponent side.

Really annoying, don’t understand what stand underhood.

I don’t know if it helps you or not, but here is the auto generated Java wrapper for that webcomponent (see attachment).

One thing to notice is the @Synchronize annotation for the getSelectedItems:

@Synchronize(property = "selectedItems", value = "selected-items-changed")
protected JsonObject getSelectedItemsJsonObject() {
    return (JsonObject) getElement().getPropertyRaw("selectedItems");
}


Gilberto
17319982.java (22.1 KB)

Hi, thanks for your answer.

I tried to use the module flow-generated-components but without success!
So I tried your generated code but unfortunately it’s doesn’t work (Cast exception).

To make it work (without exception), I modified JsonObject to JreJsonArray.
Then the problem is that JreJsonArray contains only the first value selected from UI and never change, even if I clear the selection.
Same for the listener, it’s called only once.

There is no example that Vaadin Team made using array and synchronize it from client to server?

I’m gonna try in a different way… hope it will work.

Thanks again.

Can you paste it the exception you’re having? The elemental.json.Jsonobject class is used extensively across the framework.

I mixed the configuration with the Java API and template.
Maybe it’s due to that… but I don’t know how to convert List to JsonObject.
Here is the code and the exception:

@Id("mscb")
private GeneratedMultiSelectComboBox generatedMscb;
[...]

generatedMscb.setValueField("id");
generatedMscb.setDisplayField("name");
generatedMscb.addSelectedItemsChangeListener(e -> logger.info("new item selected ?"));
<multi-select-combo-box id="mscb" items="[[entities]
]"></multi-select-combo-box>
java.lang.ClassCastException: elemental.json.impl.JreJsonArray cannot be cast to elemental.json.JsonObject
	at com.vaadin.starter.beveragebuddy.z1_ui.GeneratedMultiSelectComboBox.getSelectedItemsJsonObject(GeneratedMultiSelectComboBox.java:132)
	at com.vaadin.starter.beveragebuddy.z1_ui.GeneratedMultiSelectComboBox$SelectedItemsChangeEvent.<init>(GeneratedMultiSelectComboBox.java:632)
	at com.vaadin.starter.beveragebuddy.z1_ui.GeneratedMultiSelectComboBox.lambda$0(GeneratedMultiSelectComboBox.java:652)
	at com.vaadin.flow.internal.nodefeature.ElementPropertyMap.lambda$fireEvent$5(ElementPropertyMap.java:402)
	at java.util.ArrayList.forEach(ArrayList.java:1249)
	at com.vaadin.flow.internal.nodefeature.ElementPropertyMap.fireEvent(ElementPropertyMap.java:402)
	at com.vaadin.flow.internal.nodefeature.ElementPropertyMap.access$100(ElementPropertyMap.java:48)
	at com.vaadin.flow.internal.nodefeature.ElementPropertyMap$PutResult.run(ElementPropertyMap.java:170)
	at java.util.ArrayList.forEach(ArrayList.java:1249)
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:366)
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:309)
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89)
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1486)
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:300)

I think the problem is that I provide items attribute directly in template and not via the Java API, am I right?

If so, how can I convert the List of beans in Java to provide it via the API?

Thanks a lot for your answers.

Regards,

One thing you can try is to change the generated code to use elemental.json.JsonArray instead of JsonObject. The code analyzer couldn’t identify that field as being an array, so it used an object.

Now, why only the first item is transmitted, that’s a good question. You’d need to debug it to see where the problem is: on the client-side (that doesn’t send the data) or on the server-side (that receives the data but discards part of it). A look on the network tab of the browser developer tools should give a hint.


Gilberto

Hi, OK I will give a try and make you a feedback.

FYI, the problem is on the client side. As you said I have already check in the network tab if there was an request on the 2nd selected item but nothing and no error in the console.

Need to take few time to inspect the source of the webcomponent.

Again, thanks a lot Gilberto.

Hi, finally I rewrote my own component and added some event and data.

I hadn’t enough time to investigate why there was only the first event sended to the server side.
I want to thank you a lot Gilberto.

Hey, is everything working now?

Let us know if you have any problems :slight_smile:


Gilberto

Yeah, everything is OK!

I have 2 listeners in my component, one for new added item and one for removed item.

Then I keep the full list of selected items as attribute in my component.

We’re a little in hurry for now, maybe I will post my component as vaadin add-on.

Thanks again !

Hey there,

Glad you managed to make it work. But as a matter of fact, Flow should be easier to use in those cases. A ticket has been created related to this, and we will investigate a better solution: https://github.com/vaadin/flow/issues/4697

Please feel free to comment on the ticket.

–Gilberto