Search code examples
kotlin-multiplatformkotlin-js

How to use MessageEventInit with window.addEventListener


I am trying to register a webmessage channel using kotlin-js, but am unable to determine how to get access to the MessageEventInit type.

https://kotlinlang.org/api/latest/jvm/stdlib/org.w3c.dom/-message-event-init/index.html

The window.addEventListener method only exposes a generic Event type

https://kotlinlang.org/api/latest/jvm/stdlib/org.w3c.dom.events/-event-target/add-event-listener.html

fun addEventListener(
    type: String,
    callback: EventListener?,
    options: dynamic = definedExternally)
fun addEventListener(
    type: String,
    callback: ((Event) -> Unit)?,
    options: dynamic = definedExternally)

This is what I've come up with so far, but am having a hard time building the project.

fun configureChannel() {
    val channel = MessageChannel()
    var jsPortOne = channel.port1
    var jsPortTwo = channel.port2

    window.addEventListener("message", {
    }, false)

    jsPortOne.addEventListener("message", {
        window.alert((it as MessageEvent).data.toString())
    }, false)

    jsPortTwo.addEventListener("message", {
        window.alert((it as MessageEvent).data.toString())
    }, false)

    jsPortOne.start()
    jsPortTwo.start()
}

My primary goal is to convert this file to Kotlin/JS and combine it with this kotlin android project

https://github.com/darran-kelinske-fivestars/cordova-alternative-pattern/blob/master/app/src/main/assets/js/index.js


Solution

  • The hunch was correct. I was able to get the project building and deployed. To use a MessageEvent type in Kotlin/JS you need to cast the event to MessageEvent

    val event = it as MessageEvent

    Here is a sample:

    @JsName("configureChannel")
    fun configureChannel() {
        console.log("Configuring channel")
        window.addEventListener("message", {
    
            val event = it as MessageEvent
    
            if (event.data != KEY_CAPTURE_PORT) {
                console.log("event.data: ${event.data}")
                inputPort.postMessage(event.data)
            } else if (event.data == KEY_CAPTURE_PORT) {
                console.log("assigning captured port")
                outputPort = event.ports[0]
            }
        }, false)
    
        inputPort.start()
        outputPort.start()
    }