0

I am new to Scala and I need to figure out how to process a JSON depending on two scenarios.

First is where I receive such a JSON: {..."field":[{"count":1,"value":"foo"}]...}
Second scenario is where I receive this kind of JSON: {..."field":"foo"...}

I can not determine when each JSON will come in(it is random). In both scenarios I need to get the field value and store as a String into separate JSON. Second scenario is obvious as it is a String already but I can not figure out how to determine whenever this field is Array or String and if Array then get the "foo" from JSON within it. I know how to access the field as it is a cursor:
val field = cursor.downField("foo").downField("bar").downField("lorem").downField("field")
Below example of my approach which is not working:

if (field.asInstanceOf[String]) {
    rowFiltered.set("field", field.as[String])
} else {
    rowFiltered.set("field", field.as[Seq[field[0]]])
}

Help with determining and assigning will be appreciated.

1
  • Looks like it should isInstanceOf rather than asInstanceOf but perhaps that is a typo. Commented Oct 7, 2021 at 9:45

1 Answer 1

1

You can use orElse and pass another parsing.

import io.circe._
import io.circe.literal.JsonStringContext


object App {

  final case class MyField(value: String)

  def main(args: Array[String]): Unit = {
    val jsonValue01: Json =
      json"""{
            "hello": "world",
            "field":[{"count":1,"value":"foo01"}],
            "foo" : "bar"
            }"""

    val jsonValue02: Json =
      json"""{
            "hello": "world",
            "field": "foo02",
            "foo" : "bar"
            }"""

    implicit val decodeField: Decoder[MyField] = new Decoder[MyField] {
      final def apply(c: HCursor): Decoder.Result[MyField] =
        for {
          foo <- c.downField("field").downN(0).downField("value").as[String]
                  .orElse(c.downField("field").as[String])
        } yield {
          new MyField(foo)
        }
    }

    val myField01 = jsonValue01.as[MyField]
    val myField02 = jsonValue02.as[MyField]

    println(myField01) //Right(MyField(value = foo01))
    println(myField02) //Right(MyField(value = foo02))

  }
}


Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your input! I'm facing now the following error with your approach: value orErase is not a mamber of io.circe.Decored.Result[String]
I've tried to change the input values, as I have a hcursor as input and tried to do val field = data.hcursor.downField('foo').downField('bar').as[io.circe.Json] but received erros as well
It's not orErase but orElse
Imported import cats.syntax.either._ and works fine, thank you, will verify if the data will be extracted correctly, thanks one again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.