For example, we have this structure:
data class Item(
val city: String,
val name: String
)
val structure = mapOf("items" to listOf(
Item("NY", "Bill"),
Item("Test", "Test2"))
)
And I want to get this object in Javascript:
var structure = {
"items": [
{
"city": "NY",
"name": "Bill"
},
{
"city": "Test",
"name": "Test2"
}
]
}
How we could convert map
from Kotlin to dynamic
type with such structure in Javascript?
I find only this explicit way:
fun Map<String, Any>.toJs(): dynamic {
val result: dynamic = object {}
for ((key, value) in this) {
when (value) {
is String -> result[key] = value
is List<*> -> result[key] = (value as List<Any>).toJs()
else -> throw RuntimeException("value has invalid type")
}
}
return result
}
fun List<Any>.toJs(): dynamic {
val result: dynamic = js("[]")
for (value in this) {
when (value) {
is String -> result.push(value)
is Item -> result.push(value.toJs())
else -> throw RuntimeException("value has invalid type")
}
}
return result
}
fun Item.toJs(): dynamic {
val result: dynamic = object {}
result["city"] = this.city
result["name"] = this.name
return result
}
I know that is possible to do this also with serialization/deserialization, but I think it will be slower and with some overhead.
Does anybody know simple way to covert Kotlin object
to plain Javascript object
(dynamic
Kotlin type)?
You can do that using this simple function
inline fun <I> objectOf(
jsonObject: I = js("new Object()").unsafeCast<I>(),
writer: I.() -> Unit
): I {
writer(jsonObject)
return jsonObject
}
Usage:
interface Structure {
var items: Array<Item>
interface Item {
var city: String
var name: String
}
}
fun main() {
val structure0 = objectOf<dynamic> {
items = arrayOf<dynamic>(
objectOf {
city = "NY"
name = "Bill"
orAnything = "Literly, anything!"
},
objectOf { city = "Test"; name = "Test2" }
)
}
println(JSON.stringify(structure0))
// {"items":[{"city":"NY","name":"Bill","orAnything":"Literly, anything!"},{"city":"Test","name":"Test2"}]}
val structure1 = objectOf<Structure> {
items = arrayOf(
objectOf {
city = "NY"
name = "Bill"
// orAnything = "Literly anything" // Compile time Error: Unresolved reference: orAnything
},
objectOf {
city = "Test"
name = "Test2"
}
)
}
println(JSON.stringify(structure1))
// {"items":[{"city":"NY","name":"Bill"},{"city":"Test","name":"Test2"}]}
val structure2 = objectOf(structure1) {
items.forEach {
it.city = "Khartoum"
}
}
println(JSON.stringify(structure2))
// {"items":[{"city":"Khartoum","name":"Bill"},{"city":"Khartoum","name":"Test2"}]}
val structure3 = objectOf(structure0) {
items.unsafeCast<Array<dynamic>>().forEach {
it.name = "Shalaga44"
}
}
println(JSON.stringify(structure3))
//{"items":[{"city":"NY","name":"Shalaga44","orAnything":"Literly, anything!"},{"city":"Test","name":"Shalaga44"}]}
}