can anyone let me know, how to get a callback 'sc...
# javascript
r
can anyone let me know, how to get a callback 'script.onload' in following code for kotln/wasm or js?, I basically want a continuation excepton, when error occurred
Copy code
fun createScriptOnErrorHandler(url: String): ContextFunction<Void, Tuple1<js.core.JsAny>, Tuple1<js.core.JsAny?>> {
    return ContextFunction(
        "event", body = """
         try {
            const errorMessage = "Error loading script: $url. Message: " + event.message +
                                 ", Source: " + event.filename +
                                 ", Line: " + event.lineno +
                                 ", Col: " + event.colno +
                                 ", Error: " + event.error;

            console.error(errorMessage);

            if (typeof window !== 'undefined' && typeof window.onScriptErrorCallback === 'function') {
                window.onScriptErrorCallback(errorMessage);
            }
        } catch (e) {
            console.error("Exception in error handler: ", e);
        }

        return null;
    """.trimIndent()
    )
}

suspend fun loadJsScript(url: String, id: String) {
    suspendCoroutine<Unit> { continuation ->

        val script = document.createElement("script") as HTMLScriptElement
        script.src = url
        script.id = appCreateElement(id)
        script.type = "application/javascript"

        script.onerror = createScriptOnErrorHandler(url)
        script.onload = EventHandler { _: Event ->
            println("Script loaded: $url")
            continuation.resume(Unit)
        }

        document.head.appendChild(script)
    }
}
t
onerror
is called only when the browser is not able to load "something" from the server. For example: • it is NOT called if the script does not exists but the server returns with something, let's say
index.html
instead • it also does NOT work if the script has an error that prevents compilation This code worked for me (it does not handle the two points above):
Copy code
suspend fun loadJsScript(url: String, id: String) {
    suspendCoroutine<Unit> { cont ->
        val script = document.createElement("script") as HTMLScriptElement
        script.src = url
        script.id = "23"
        script.type = "application/javascript"

        script.addEventListener("error", { _: Event ->
            cont.resumeWithException(RuntimeException("Failed to load script: $url"))
        })

        script.onload = { event: Event ->
            console.log(event)
            println("Script loaded: $url")
        }

        document.head?.appendChild(script)
    }
}
👍 1
r
appreciated, and thanks for the time and effort, but i am more specifically looking for ''onerror'
t
You have to use window.onerror for that I think. From: https://mdn2.netlify.app/en-us/docs/web/api/globaleventhandlers/onerror/
For historical reasons, different arguments are passed to
window.onerror
and `element.onerror`handlers (as well as on error-type
EventTarget.addEventListener
handlers).
I've tried with window.onerror:
Copy code
window.onerror = { message, source, lineno, colno, error ->
            println("Error: $message $source $lineno $colno $error")
            cont.resumeWithException(RuntimeException("Failed to load script: $url $message $source $lineno $colno $error"))
        }
The result:
This looks fine, but the
onload
on script is still called as there is a response from the server. I think you need some logic to handle the different cases.
r
i can consider it, but is there anyway specific to script.oneerror, that i can use, as window wil llisten for any error in this case,
t
It won't work I think. The onerror of the element won't get the information you want. Only the window onerror gets that information. Kotlin/JS providing the function signature doesn't mean anything actually.
r
i am not worried about the info, i had tried to use expect/actuall for that as well, it worked for js but failed for wasm
i just need a callback
t
I think you can do it if you use both. The element.onerror for file load error detection and window.onerror for the syntax error detection.
I guess it failed on wasm because the parameters are different, but that's just a guess.
r
it always gives me undefined for lenght in wasm, although i was not using anyway the error
t
For all available events you can use strict adapters.
errorEvent
and
loadEvent
in this case:
Copy code
suspend fun loadJsScript(url: String, id: String) {
    suspendCoroutine<Unit> { cont ->
        val script = document.createElement(HtmlTagName.script)
        script.src = url
        script.id = "23"
        script.type = "application/javascript"

        script.errorEvent.addHandler {
            cont.resumeWithException(RuntimeException("Failed to load script: $url"))
        }

        script.loadEvent.addHandler {
            console.log(event)
            println("Script loaded: $url")
        }

        document.head?.appendChild(script)
    }
}
windor.onerror
signature is weird (for historical reasons) and it's better to use more strict accessors
r
i guess, this is what i was looking for, i had explored earlier till, script.errorEvent. but handler was missing, thanks
@turansky but link.errorEvent.addHandler
Copy code
suspend fun loadCss(url: String, id: String) {
    suspendCoroutine<Unit> { continuation ->
        val link = document.createElement("link") as HTMLLinkElement
        link.rel = "stylesheet"
        link.href = url
        link.id = appCreateElement(id)
        link.type = "text/css"

        /*link.errorEvent.addHandler {
            continuation.resumeWithException(RuntimeException("Failed to load script: $url"))
        }*/

        link.loadEvent.addHandler {
            println("CSS loaded: $url")
            continuation.resume(Unit)
        }
        document.head.appendChild(link)
    }
}
is getting called for other error as well, not specifict to this script, is there anything, from where i can handle specific to this script only
t
Looks strange :(
It's not what I see in documentation
t
Does `loadEvent.addHandler`do anything special? Or does it just add the event handler with addEventListener?
If it doesn't (do anything special) then I think the problem is still the actual difference of HTMLElement.error and Window.error.
t
Does `loadEvent.addHandler`do anything special?
Accessor give you knowledge, that such event is known for this target