Alex Styl
12/17/2024, 1:42 PM@Serialized data class or do i need to do the mapping on my own?
context: I have a kotlin library with functions that take data classes as params. I tried using it as is from javascript and pass javascript objects but it didn't work (getting all sorts of errors), so I am assuming the types are wrong. so my assumption is someone needs to do the mapping and was wondering if there is a baked in way for this scenarioAlex Styl
12/17/2024, 1:55 PM@JsExport , which take dynamic as params and doing the mapping manuallyArtem Kobzar
12/17/2024, 4:05 PMAlex Styl
12/18/2024, 3:51 PMMyDataClass data class.
I send it to my server using ktor + the serialization lib:
val response = <http://httpClient.post|httpClient.post>("/api/process") {
contentType(ContentType.Application.Json)
val bodyString = Json.encodeToString<MyDataClass>(data)
setBody(bodyString)
}
My Server is an express js server:
<http://app.post|app.post>('/api/process', async (req, res) => {
const data = req.body;
I want to process that data using kotlin, so i made a kotlin npm package with a related function:
fun processData(data: MyDataClass) = TODO()
The question is. How I do call this kotlin function from javascript without having type mismatches?
I tried marking it with @JsExport and calling it directly in javascript, passing the javascript object as parameter, but my kotlin code was crashing with some weird obscure errors.
What I found works is create a function with dynamic parameter and do the mapping mannually:
@JsExport
fun processData(data: dynamic) {
val myClassData : MyDataClass = ...
return processData(myClassData)
}
fun processData(data: MyDataClass) = TODO()
Do I need to do this mapping manually or is there an other way to do it?Artem Kobzar
12/18/2024, 5:49 PMMyDataClass from the JSON parsed on the express side.
One of the options you can do (ofc if your express controller is supposed to be used only with the MyDataClass) is to tell express not to parse the request body (so it will be a text) and, from the Kotlin side, deserialize the class using kotlinx.serialization. As a sketch, it would look like this:
// Express side
// Variant 1
app.use(express.json()); // You can remove the line if all of your controllers work only with the Kotlin data
// Variant 2
app.post('/api/process', express.text({ type: '*/*' }), async (req, res) => { // If only several routes should be parsed by kotlinx.serialization
const data = req.body;
// And depends on the variants below, your route body would look like this:
async (req, res) => {
processData(parseMyDataClass(req.body))
}
// Or like this
async (req, res) => {
processData(req.body)
}
// Kotlin side
// You can do like this
@JsExport
fun parseMyDataClass(data: String): MyDataClass = Json.decodeFromString<MyDataClass>(data)
@JsExport
fun processData(data: MyDataClass) = TODO()
// Or like this
@JsExport
fun processData(data: String) {
val myData = Json.decodeFromString<MyDataClass>(data)
TODO()
}Artem Kobzar
12/18/2024, 5:50 PMArtem Kobzar
12/18/2024, 5:50 PMAlex Styl
12/20/2024, 3:51 AM