Here is what I am trying to do
case class MessageModel (time: Long, content: String) {}
val message = MessageModel(123, "Hello World")
def jsonParser[A] (obj: A) : String = obj.asJson.noSpaces
println jsonParser[MessageModel](message)
this doesn't work, because it will complain Error:(13, 8) could not find implicit value for parameter encoder: io.circe.Encoder[A] obj.asJson.noSpaces ^
I kind of understand why it is happening, but is there a way to work around it?
Thanks
Circe is a Scala library that simplifies working with JSON, allowing us to easily decode a JSON string into a Scala object or convert a Scala object to JSON. The library automatically generates the object encoders and decoders, thereby reducing the lines of code we need to work with JSON in Scala.
Encoding and decoding in circe are provided by type classes, which means that you have to be able to prove at compile time that you have a type class instance for A
if you want to encode (or decode) a value of type A
.
This means that when you write something like this:
import io.circe.syntax._
def jsonPrinter[A](obj: A): String = obj.asJson.noSpaces
You're not providing enough information about A
for circe to be able to print values of that type. You can fix this with a context bound:
import io.circe.Encoder
import io.circe.syntax._
def jsonPrinter[A: Encoder](obj: A): String = obj.asJson.noSpaces
Which is Scala's syntactic sugar for something like this:
def jsonPrinter[A](obj: A)(implicit encoder: Encoder[A]): String =
obj.asJson.noSpaces
Both of these will compile, and you can pass them a value of any type that has an implicit Encoder
instance. For your MessageModel
specifically, you could use circe's generic derivation, since it's a case class:
scala> import io.circe.generic.auto._
import io.circe.generic.auto._
scala> case class MessageModel(time: Long, content: String)
defined class MessageModel
scala> val message = MessageModel(123, "Hello World")
message: MessageModel = MessageModel(123,Hello World)
scala> jsonPrinter(message)
res0: String = {"time":123,"content":"Hello World"}
Note that this wouldn't work without the auto
import, which is providing Encoder
instances for any case class (or sealed trait hierarchy) whose members are all also encodeable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With