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 ...}
bashor
  • 8,073
  • 4
  • 34
  • 33
John Abraham
  • 183
  • 1
  • 4

8 Answers8

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
}
bashor
  • 8,073
  • 4
  • 34
  • 33
  • 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 work – John Abraham Jan 26 '15 at 15:16
  • 1
    2017 calling, trying to do the same as OP. is this answer outdated? – birgersp Nov 14 '17 at 14:32
  • @gromit190 the answer looks like actual, please let me know if you have any problem with it. – bashor Mar 25 '18 at 12:30
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;
Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
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.

Sharp
  • 111
  • 1
  • 6
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
    )
)
skr
  • 21
  • 2
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
}
Vlad
  • 7,997
  • 3
  • 56
  • 43
HughG
  • 1,108
  • 10
  • 14
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)
eyelash
  • 3,197
  • 25
  • 33
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"
Simon Jacobs
  • 1,147
  • 7
  • 7
0

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"
Raman
  • 17,606
  • 5
  • 95
  • 112