javascript anonymous object in kotlin
Asked Answered
S

8

18

how to create JavaScript anonymous object in kotlin? i want to create exactly this object to be passed to nodejs app

var header = {“content-type”:”text/plain” , “content-length” : 50 ...}
Saltigrade answered 26/1, 2015 at 12:27 Comment(0)
V
26

Possible solutions:

1) with js function:

val header = js("({'content-type':'text/plain' , 'content-length' : 50 ...})") 

note: the parentheses are mandatory

2) with dynamic:

val d: dynamic = object{}
d["content-type"] = "text/plain"
d["content-length"] = 50

3) with js + dynamic:

val d = js("({})")
d["content-type"] = "text/plain"
d["content-length"] = 50

4) with native declaration:

native
class Object {
  nativeGetter
  fun get(prop: String): dynamic = noImpl

  nativeSetter
  fun set(prop: String, value: dynamic) {}
}

fun main(args : Array<String>) {
  var o = Object()
  o["content-type"] = "text/plain"
  o["content-length"] = 50
}
Venditti answered 26/1, 2015 at 13:19 Comment(3)
thanks for quick reply first solution may work but it is not flexible i mean it is hard coded value and i am getting some errors as well you can check it. 2nd solution creates Kotlin.createObject(.....) on javascript side i can't pass this to node.js this doesn't workSaltigrade
2017 calling, trying to do the same as OP. is this answer outdated?Wellfavored
@gromit190 the answer looks like actual, please let me know if you have any problem with it.Venditti
K
13

Here's a helper function to initialize an object with a lambda syntax

inline fun jsObject(init: dynamic.() -> Unit): dynamic {
    val o = js("{}")
    init(o)
    return o
}

Usage:

jsObject {
    foo = "bar"
    baz = 1
}

Emited javascript code

var o = {};
o.foo = 'bar';
o.baz = 1;
Kaufman answered 19/11, 2017 at 17:57 Comment(3)
this is the only one that worked for me, lifesaver!Churchwoman
The return Type can "dynamic" to "Json". e.g. inline fun jsObject(init: dynamic.() -> Unit): Json {} This will more than safe.Chilt
using this in kotlin/wasm, i get dynamic not supported in this contextTosh
D
6

One more possible solution:

object {
        val `content-type` = "text/plain"
        val `content-length` = 50
}

It seems that it does not work anymore with escaped variable names.

Dogs answered 27/1, 2015 at 11:39 Comment(2)
is this "possible" or does it work and do the same thing?Vedette
Thanks @JaysonMinard, I fixed my answer.Dogs
C
2

In my Kotlin/JS + React project I have written an adapter for a library that accepts an anonymous configuration object through the constructor. After searching for a while I found a solution using kotlin.js.json

val options = json(
    "position" to "top-right",
    "durations" to json(
        "global" to 20000
    )
)
Crashland answered 30/1, 2022 at 21:36 Comment(0)
T
1

I'm a Kotlin newbie (though not a newbie developer), I slightly extended answer from @bashor to something looks neater for keys which are valid Java identifiers, but still allows ones which aren't. I tested it with Kotlin 1.0.1.

@JsName("Object")
open class Object {
}

fun jsobject(init: dynamic.() -> Unit): dynamic {
    return Object().apply(init)
}

header = jsobject {
    validJavaIdentifier = 0.2
    this["content-type"] = "text/plain"
    this["content-length"] = 50
}
Timm answered 30/3, 2016 at 11:49 Comment(2)
Object() may be replaced with js("{}")Daredeviltry
This is the same and shorter fun jsObject(init: dynamic.() -> Unit) = js("{}").apply(init)Daredeviltry
D
1

Here is another solution:
Define the following helper function

fun jsObject(vararg pairs: Pair<Any, Any>): dynamic {
    val result = js("({})")
    for ((key, value) in pairs) {
        result[key] = value
    }
    return result
}

You can then use it as follows

val header = jsObject("content-type" to "text/plain", "content-length" to 50)
Dola answered 3/12, 2019 at 0:12 Comment(0)
G
0

It is possible to transform a regular Kotlin object into a JavaScript anonymous object using JavaScript's Object.assign(). This allows you to stay in pure Kotlin and in type-safety as long as possible. So:

fun Any.toJsObject(): dynamic {
    val thisArg = this                       // Allows use in js() function
    return js("Object.assign({},thisArg)")
}

val anObject = object { val a = "a" }        // Or use a regular class
console.log( anObject.toJsObject().a )       // logs "a"
Gymkhana answered 11/5, 2020 at 2:38 Comment(0)
V
-1

The Kotlin/JS standard library has a Json interface, and a json factory function taking in a vararg of Pair<String, Any?>.

val header = json(
  "content-type" to "text/plain",
  "content-length" to 50,
)
    
header["x-another-header"] = "foo"
Valenzuela answered 15/3, 2023 at 20:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.