Hi. Do you know any library that is in Kotlin and ...
# multiplatform
g
Hi. Do you know any library that is in Kotlin and can search for specific key in a Json and return it? There is a website Im scraping and it's API call returns huge JSON text out of which 99% is useless for me. There is just one Array I need to find and this is how I suffer :
Copy code
((Json.decodeFromString<JsonObject>(response.bodyAsText())["onResponseReceivedActions"] as JsonArray)[0] as JsonObject)["reloadContinuationItemsCommand"]
If I use
JSON to kotlin class
plugin then I get 110 different objects and for some reason the code does not compile
e
👀 1
g
Thanks, it looks very promissing, including the PR
🚀
k
If you set kolinx serialization to ignore unknown keys
Copy code
val json = Json {
  ignorUnknownKeys = true
}
and then write your model as
Copy code
@Serializable class Response(
  val onResponseReceivedAction: List<SomeType>
)
You should be able to do this
c
I never published it as a library, but a while ago I made a little utility for a pure kotlin JsonPointer using kotlinx.serialization `JsonElement`s. It’s not as powerful as JsonPath, but it is simpler and pure-kotlin, plus it also allows a similar syntax for updating the JSON object as well. You’re welcome to copy the sources into your project.
m
I have this that I copy paste in each of my project:
Copy code
fun JsonElement.toAny(): Any? {...}

inline fun <reified T> Any?.cast() = this as T

val Any?.asMap: Map<String, Any?>
    get() = this.cast()
val Any?.asList: List<Any?>
    get() = this.cast()
val Any?.asString: String
    get() = this.cast()
val Any?.asBoolean: String
    get() = this.cast()
val Any?.asNumber: Number
    get() = this.cast()
Then you can write
Copy code
Json.decodeFromString(response.text())
   ?.asMap["onResponseReceivedActions"]
   ?.asList[0]
   ?.asMap["reloadContinuationItemsCommand"]
It's not perfect but you don't have to go back all the time to open those cast parenthesis yell at parenthesis
e
why? if you just use the extensions already in kotlinx.serialization.json:
Copy code
Json.decodeFromString<JsonElement>(response.bodyAsText())
    .jsonObject["onResponseReceivedActions"]!!
    .jsonArray[0]
    .jsonObject["reloadContinuationItemsCommand"]!!
    .jsonPrimitive.content
💡 2
👍 2
K 1
m
Not sure exactly why I liked working with Maps and List better than
JsonElement
. I guess the
.jsonObject
vs
.asObject
got me a bit confused initially and I never questioned this again. Also I'd really like to see this
cast<T>()
method reach stdlib one day so I'm practicing it 😄
m
you can use kotlinx serialisation library and create a data class containing only the values you're looking for?
m
why? if you just use the extensions already in kotlinx.serialization.json
Just bumped into one of the reason.
.jsonPrimitive.content
will return
"null"
instead of
null
if the string is nullable so it needs extra care
Same for
.jsonObject
. If you object is nullable, it'll throw so you'll have to manage that manually at which point might as well write your own extensions