Kotlin Js issue with fetch api


#1

I’m converting some plain js code to koltin-js and I’m having issues with the fetch api with even basic requests like this:

window.fetch(url,
        init = RequestInit(credentials = RequestCredentials.SAME_ORIGIN))

this generates the error:

Uncaught (in promise) TypeError: Failed to execute ‘fetch’ on ‘Window’: The provided value ‘null’ is not a valid enum value of type RequestCache.

I can get it to work but I have to add a few extra things like “cache = undefined” and “redirect = undefined”

Also when I do add these and get it to work I keep getting warnings in the console like this:

Error parsing ‘integrity’ attribute (‘null’). The hash algorithm must be one of ‘sha256’, ‘sha384’, or ‘sha512’, followed by a ‘-’ character.

The pure javascript solution doesn’t have any of these issues.

I’m using kotlin-js 1.2.71


#2

Same issue, it’s rather annoying that even sending a simple POST request somewhere is quite the challenging task in KotlinJS if someone is not familiar with Javascript.


#3

Just encountered this in my project. That is really annoying. The problem is this convenience function from the kotlin-js stdlib:

public inline fun RequestInit(
    method: String? = null, 
    headers: dynamic = null, 
    body: dynamic = null, 
    referrer: String? = null, 
    referrerPolicy: dynamic = null, 
    mode: RequestMode? = null, 
    credentials: RequestCredentials? = null, 
    cache: RequestCache? = null, 
    redirect: RequestRedirect? = null, 
    integrity: String? = null, 
    keepalive: Boolean? = null, 
    window: Any? = null
): RequestInit { ...

This “convenience” function declares most arguments as optional, with a default value “null”. The problem is, the web fetch API does not allow null for those arguments. They must be non-null or undefined.

This is not a convenience function, rather an inconvenience function.


#4

Try creating your own RequestInit method that uses undefined instead of null.

public fun RequestInit(method: String? = undefined, headers: dynamic = undefined, body: dynamic = undefined, referrer: String? = undefined, referrerPolicy: dynamic = undefined, mode: RequestMode? = undefined, credentials: RequestCredentials? = undefined, cache: RequestCache? = undefined, redirect: RequestRedirect? = undefined, integrity: String? = undefined, keepalive: Boolean? = undefined, window: Any? = undefined): RequestInit {
	val o = js("({})")

	o["method"] = method
	o["headers"] = headers
	o["body"] = body
	o["referrer"] = referrer
	o["referrerPolicy"] = referrerPolicy
	o["mode"] = mode
	o["credentials"] = credentials
	o["cache"] = cache
	o["redirect"] = redirect
	o["integrity"] = integrity
	o["keepalive"] = keepalive
	o["window"] = window

	return o
}

#5

I know how to solve it. I ended up using my already existing convenience API for creating dynamic js objects.

Your particular solution is too dangerous in my opinion. It is too easy to import the wrong RequestInit function.

Anyhow, it’s just sad, that the function from the kotlinjs stdlib is effectively unusable.


#6

Their JS side isn’t as widely used as their JVM side – they need a lot of user feedback for it.