Klue Klue - 4 months ago 21
JSON Question

Error message: Try to implement an implicit Writes or Format for this type

I have the following json string. In scala I want to extract some fields and save them in a new json.


{"query":"doi:10.1186/s13612-016-0045-3","result":[{"total":"1","start":"1","pageLength":"10"}],"records":[{"identifier":"doi:10.1186/s13612-016-0045-3","url":[{"format":"","platform":"","value":"http://dx.doi.org/10.1186/s13612-016-0045-3"}],"title":"Technology
and Reflection: Mood and Memory Mechanisms for
Well-Being","creators":[{"creator":"Konrad,
Artie"},{"creator":"Tucker, Simon"},{"creator":"Crane,
John"},{"creator":"Whittaker, Steve"}],"publicationName":"Psychology
of
Well-Being","issn":"2211-1522","openaccess":"true","journalid":"13612","doi":"10.1186/s13612-016-0045-3","publisher":"Springer","publicationDate":"2016-06-15","volume":"6","number":"1","issuetype":"","topicalCollection":"","startingPage":"1","copyright":"©2016
The
Author(s)","genre":"OriginalPaper","abstract":"AbstractBackgroundWe
report a
..."}],"facets":[{"name":"subject","values":[{"value":"Biological
Psychology","count":"1"},{"value":"Health
Psychology","count":"1"},{"value":"Neuropsychology","count":"1"},{"value":"Positive
Psychology","count":"1"},{"value":"Psychology","count":"1"},{"value":"Quality
of Life
Research","count":"1"}]},{"name":"pub","values":[{"value":"Psychology
of
Well-Being","count":"1"}]},{"name":"year","values":[{"value":"2016","count":"1"}]},{"name":"country","values":[{"value":"United
States","count":"1"},{"value":"USA","count":"1"}]},{"name":"type","values":[{"value":"Journal","count":"1"}]},{"name":"keyword","values":[{"value":"Emotion","count":"1"},{"value":"Memory","count":"1"},{"value":"Mood","count":"1"},{"value":"Reflection","count":"1"},{"value":"Reminiscence","count":"1"},{"value":"Technology
mediated
reflection","count":"1"},{"value":"Well-being","count":"1"}]}]}


In particular I want to get the following new json object (i.e. extract fields "creators","publicationName" and "abstract", and rename them accordingly):


{"creators":[{"creator":"Konrad, Artie"},{"creator":"Tucker,
Simon"},{"creator":"Crane, John"},{"creator":"Whittaker,
Steve"}],"pubTitle":"Psychology of
Well-Being","pubAbstract":"AbstractBackgroundWe report ..."}


This is my current code, but I the error message says
Error:(137, 27) No Json serializer found for type play.api.libs.json.JsResult[org.test.Publication]. Try to implement an implicit Writes or Format for this type. val json = Json.toJson(processedPubl)
.

import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.data.validation.ValidationError
import play.api.libs.json.Reads._

case class Creator(creator: String)
case class Publication(pubTitle: String, creators: Seq[Creator], pubAbstract: String)

val jsonstring = ... // this is the raw string provided
// at the beginning of this post

implicit val publReads: Reads[Publication] = (
(JsPath \ "publicationName").read[String] and
(JsPath \ "creators").read[Seq[Creator]] and
(JsPath \ "abstract").read[String]
) (Publication.apply _)

val processedPubl = Json.parse(jsonstring).validate[Publication](publReads)

val json = Json.toJson(processedPubl)

Answer

You should try this:

import play.api.libs.functional.syntax._
import play.api.libs.json._

case class Creator(creator: String)
case class Publication(pubTitle: String, creators: Seq[Creator], pubAbstract: String)

val jsonString = ...

implicit val creatorFormat = Json.format[Creator]
implicit val publWrites = Json.writes[Publication]
implicit val publReads: Reads[Publication] = (
  (JsPath \ "publicationName").read[String] and
  (JsPath \ "creators").read[Seq[Creator]] and
  (JsPath \ "abstract").read[String]
)(Publication.apply _)

val input = Json.parse(jsonString).as[Publication]
val output = Json.toJson(input)

Reads is something that is used during reading from JSON (input uses this) and Writes is something that is used during writing to JSON (output uses it). Together they form something called Format. Since you're using case classes in your code, you can autogenerate those Reads/Writes/Formats using play-json methods.

Comments