sk1007
sk1007

Reputation: 581

Scala compile errors: "No implicit view available" and "diverging implicit expansion"

 def MyFun(result: ListBuffer[(String, DateTime, List[(String, Int)])]):
 String = {
 val json =
  (result.map {
    item => (
      ("subject" -> item._1) ~
        ("time" -> item._2) ~
        ("student" -> item._3.map {
          student_description=> (
            ("name" -> lb_result._1) ~
              ("age" -> lb_result._2) 
            )
        })
      )
    }
    )
    val resultFormat = compact(render(json))
    resultFormat  
}

error 1: No implicit view available from org.joda.time.DateTime => org.json4s.JsonAST.JValue.("subject" -> item._1) ~

error 2: diverging implicit expansion for type Nothing => org.json4s.JsonAST.JValue starting with method seq2jvalue in trait JsonDSL val resultFormat = compact(render(json))

Upvotes: 2

Views: 2672

Answers (2)

Peter Neyens
Peter Neyens

Reputation: 9820

I hinted at json4s-ext for joda-time support, but only importing this submodule won't solve your problem.

JsonDSL is used to create JValues and serializers are only used to turn JValues into JSON and vise versa (serialization and deserialization).

If we try to create a simpler json object with a DateTime :

val jvalue = ("subj" -> "foo") ~ ("time" -> DateTime.now)

We get the same error :

error: No implicit view available from org.joda.time.DateTime => org.json4s.JsonAST.JValue.

Like I said, the serializers for DateTime from json4s-ext are not used when we use JsonDSL to create JValues.

You could create an implicit function DateTime => JValue or do something like DateTime.now.getMillis or DateTime.now.toString to create respectively a JInt or a JString, but why would we reinvent the wheel if joda time serializers already exist ?

We can introduce some case classes to hold the data in result and then json4s can serialize them for us :

import scala.collection.mutable.ListBuffer

import com.github.nscala_time.time.Imports._

import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization
import org.json4s.native.Serialization.{read, write}

implicit val formats = 
  Serialization.formats(NoTypeHints) ++ org.json4s.ext.JodaTimeSerializers.all

case class Lesson(subject: String, time: org.joda.time.DateTime, students: List[Student])
case class Student(name: String, age: Int)

val result = ListBuffer(("subj", DateTime.now, ("Alice", 20) :: Nil))
val lessons =  result.map { case (subj, time, students) => 
  Lesson(subj, time, students.map(Student.tupled))
}

write(lessons)
// String = [{"subject":"subj","time":"2015-09-09T11:22:59.762Z","students":[{"name":"Alice","age":20}]}]

Note that you still need to add json4s-ext like Andreas Neumann explained.

Upvotes: 6

Andreas Neumann
Andreas Neumann

Reputation: 10904

As Peter Neyens allready said for serializing org.joda.time.DateTime you ned the ext package

https://github.com/json4s/json4s#extras

So add this dependency to you build.sbt

libraryDependencies += "org.json4s" %% "json4s-ext" % "3.2.11"

Upvotes: 0

Related Questions