How to call function on web component

I am trying to integrate a autocomplete web component (https://www.webcomponents.org/element/ellipticaljs/paper-autocomplete) into my application. How do I call a method this component? I am new to Vaadin and checked the docs, but only found documentation on setting/getting attributes and properties as well as functions. My current solution is working, but requires de/serialization logic:

@DomEvent("autocomplete-change")
class ChangeEvent (source : ExerciseSelectComponent,
                   fromClient : Boolean,
                   @EventData("event.detail.option.text") val text : String) : ComponentEvent<ExerciseSelectComponent>(source, fromClient) {

}

@HtmlImport("frontend://bower_components/paper-autocomplete/paper-autocomplete.html")
@Tag("paper-autocomplete")
class ExerciseSelectComponent (private val repository: ExerciseRepository, private val objectMapper : ObjectMapper) : Component() {

    private val log = LoggerFactory.getLogger(ExerciseSelectComponent::class.java)

    init {
        element.setAttribute("min-length", "3")
        element.setAttribute("remote-source", "")

        addListener(ChangeEvent::class.java, ComponentEventListener { e ->
            val suggestions = repository.findByNameContaining(e.text).map {
                mapOf(Pair("value", it.id), Pair("text", it.name))
            }
            UI.getCurrent().page.executeJavaScript("$0.suggestions(JSON.parse($1))", element, objectMapper.writeValueAsString(suggestions))
        })
    }

}

Hi Frederik,

Sorry for the lack of documentation. We are updating them and a specific topic about client<->server communication will be available explaining how to do it.

Meanwhile, to send complex objects to the client, you can to build a object that extends the elemental.json.JsonValue type. You can build the array on your own, by using this:

JsonArray array = Json.createArray();
        
JsonObject obj = Json.createObject();
obj.put("value", value);
obj.put("text", text);
        
array.set(0, obj);        

… or if you have a pojo you can use the com.vaadin.flow.internal.JsonSerializer to serialize it for you:

List<MyPojo> pojos = ...
JsonArray array = JsonSerializer.toJson(pojo);

After you have your JsonValue, you can send it to your client by using:

// if your element has a defined function on it:
myComponent.getElement().callFunction("functionName", array);

// if you don't have a function on the element, but in some other place
UI.getCurrent().getPage().executeJavaScript("functionName($0)", array);

// if you want to set a property
UI.getCurrent().getPage().executeJavaScript("$0.propertyName = $1", myComponent.getElement(), array);

I hope it helps :slight_smile:

Thanks Gilberto, the following worked for me:

            val suggestions = repository.findByNameContaining(e.text)
                    .map {
                        val obj = Json.createObject()
                        with (obj) {
                            it.id?.let { put("value", it.toDouble()) }
                            put("text", it.name)
                        }
                        obj
                    }
                    .foldIndexed(Json.createArray(), {index, arr, obj ->
                        arr.set(index, obj)
                        arr
                    })
            element.callFunction("suggestions", suggestions)