is there any convinient way to turn data classes i...
# javascript
a
is there any convinient way to turn data classes into json objects and arrays? im writing a library that is going to be called from nodejs
a
kotlinx.serialization
is the Kotlin way to work with JSON. But it's slow on JS 😓
a
@Artem Kobzar it might be okay for my case. how do i turn it into json objects though? if u are talking about
Copy code
Json.decodeFromString<Project>(string)
it needs a type. what would the type be?
c
Do you only need this direction, or do you need both directions? Kotlin → JSON using
JSON.stringify
is relatively safe, it's
JSON.parse
that dangerous
a
i only need kotlin to json yes. I tried to do:
Copy code
// .kt
fun kotlinCode(): Any {
   val arrayWithDataClasses = ...
   return JSON.stringify(arrayWithDataClasses)
}
and then from nodejs
Copy code
val string = KotlinModule.kotlinCode()
val obj = JSON.parse(string)
but the objects look like:
Copy code
{
   l2_1 : "key",
   m2_1 : "value
}
instead of
Copy code
{
  "key": "value"
}
c
Does using
@JsExport
help?
Otherwise I guess using KotlinX.Serialization to generate a string, and then
JSON.parse
on it? That's a bit expensive of a roundtrip 😕 And also, objects created from
JSON.parse
can't be safely passed back to Kotlin down the line, so be wary of that
a
Ended up creating some adapters and doing the mapping manually for now. my case is very simple:
Copy code
fun <E> List<E>.toJsonArray(): List<dynamic> {
    val array: dynamic = js("([])")
    this.forEach {
        array.push(it)
    }
    return array
}

fun buildJsonObject(builder: MutableMap<String, dynamic>.() -> Unit): Any {
    val jsObject: dynamic = js("({})")
    val map = mutableMapOf<String, dynamic>()
    map.apply(builder)
    map.forEach { (key, value) ->
        jsObject[key] = value
    }
    return jsObject
}
c
(not very important, but for naming: in the JS world, these objects are called "plain JS objects", not "JSON objects", that's why our first answers in this thread were a bit off)
a
Is there some convenient way to turn data classes to plain js objects?
c
To my knowledge, there isn't anything more convenient than what has been said in this thread already… But it's the first time I come across this use-case, so I haven't done much research
a
Do people here usually use kotlin on top of JavaScript instead of in addition to?
c
I can't speak for everyone else. Personally, I mostly write 100% multiplatform Kotlin code that I then run on top of JS, in addition to other platforms. I sometimes have to call JS in my Kotlin, but I don't really write JS, so I never call Kotlin from JS.
👍 1
a
We call kotlin from JS alot, but we move most (if not all) of the heavy lifting into the kotlin side
e
But it's slow on JS
I need to find the benchmarks I had looked at, because perf had gotten way better over time
See https://github.com/Kotlin/kotlinx.serialization/issues/907 And @spierce7's https://github.com/ScottPierce/kx-serialization-js-benchmark You can update the Kotlin version to check for improvements.
a
You have to wait for 2.0
@JSPlainObject
https://kotlinlang.org/docs/whatsnew-eap.html#support-for-type-safe-plain-javascript-objects Then you'll be able to just use
JSON.stringify
and
JSON.parse
without having mangled fields
K 1
e
JsPlainObject
works only on externals and it basically adds a constructor to the interface declaration. So not much different to what you'd do now with
jso { }
.
a
The difference is that the fields aren't mangled
e
If the interface is external, they wouldn't be mangled anyway, even without that annotation
a
Ah ? It wasn't like this in my memories, I tried removing KXSer to one of my project and had to stop because of this limitation
p
@Artem Kobzar are there plans to improve the performance of the serialization lib on JS?
a
It's better to ask in #serialization, because seems like we can do nothing to improve this from the compiler side.
👍 1