Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Dynamic Parse Json using case class No Manifest available for T

Tags:

generics

scala

I have a JSON string and I created a function which parses this JSON as an object using Scala case class. I wrote the below code to parse it in a generic way. However, It gave me an error:

def getJsonObj[T](jsonString:String): T = {
    implicit val formats: DefaultFormats.type = DefaultFormats
      parse(jsonString).extract[T]
}

Error can be found below:

Error:(19, 32) No Manifest available for T. 
parse(jsonString).extract[T] Error:(19, 32) not enough arguments for 
method extract: (implicit formats: org.json4s.Formats, implicit mf: 
scala.reflect.Manifest[T])T. Unspecified value parameter mf.
parse(jsonString).extract[T]

I found this No Manifest available for Type But I don't know how to fix it in my code. Also, I found this,Spark Scala - How to construct Scala Map from nested JSON (Scala: "No manifest available for type T") But I need to pass the case class to the function in a generic way. It seems a common problem but I can't solve it using the available answers as I am new in Scala.

Another point, How can I add try-catch to see if it's correctly parsed or not?

like image 324
Sa2012 Avatar asked May 05 '19 10:05

Sa2012


1 Answers

I think this answer solves your question, Scala: “No manifest available for type T”. It easily solved by implicitly passing on the manifest for the type method. I add an example of the code and a simple function for error handling.

  val jsonStr: String = """{"airports":[{"name":"sfo","score":1},{"name":"phx","score":1},{"name":"sjc","score":1}]}"""

  case class AirPortScores(name: String, score: Double)
  case class JsonRulesHandler(airports: List[AirPortScores])

  val json: JsonRulesHandler = getJsonObj[JsonRulesHandler](jsonStr)
  println(json)


  def getJsonObj[T](jsonString:String)(implicit m: Manifest[T]): T = {
    extractFrom(jsonString) match {
      case Success(jsonParsed) ⇒
        jsonParsed
      case Failure(exc) ⇒
        throw new IllegalArgumentException(exc)
    }
  }

  private def extractFrom[T](jsonString:String)(implicit m: Manifest[T]): Try[T] = {
    implicit val formats: DefaultFormats.type = DefaultFormats

    Try {
      parse(jsonString).extract[T]
    }
  }
like image 194
Moustafa Mahmoud Avatar answered Jan 03 '23 19:01

Moustafa Mahmoud