agusgambina
agusgambina

Reputation: 6669

Playframework 2.4.x Json write List[(String, String)]

I am trying to update some code. I am having problem with this case class trying to write the json implicit writer

case class TemplateEmailMessage(recipients: List[EmailRecipient], globalEmailVars: List[(String, String)])

It was like this

implicit val templateEmailMessageWrites = new Writes[TemplateEmailMessage] {
        def writes(m: TemplateEmailMessage): JsValue = {
            val globalVars: List[JsValue] = m.globalEmailVars.map(g => Json.obj("name" -> g._1, "content" ->g._2))
            Json.obj(
        "to" -> m.recipients,
        "global_merge_vars" -> JsArray(globalVars)
            )
        }
    }

Now is like this. Obviously is not working because the type of the second field List[(String, String)]

object TemplateEmailMessage {

  implicit val templateEmailMessageWrites: Writes[TemplateEmailMessage] = (
    (JsPath \ "to").write[List[EmailRecipient]] and
    (JsPath \ "global_merge_vars").write[List[(String, String)]]
  )(unlift(TemplateEmailMessage.unapply))

}

I am not sure how to translate the JsArray, because before it was use to manipulate the values in the writer. I should leave like the old way or there is another way?

Thank you

Upvotes: 0

Views: 120

Answers (1)

Tomer
Tomer

Reputation: 2448

You can do it like this:

object TemplateEmailMessage{
implicit val templateEmailMessageWrites: Writes[TemplateEmailMessage] = (
  (JsPath \ "to").write[List[EmailRecipient]] and
  (JsPath \ "global_merge_vars").write[JsArray]
     .contramap[List[(String, String)]](list => JsArray(list.map(g => Json.obj("name" -> g._1, "content" ->g._2))))
 )(unlift(TemplateEmailMessage.unapply))
}

Other option, is to convert the (String, String) tuple to a case class and create a writer for it.

case class Variable(name: String, content: String)
object Variable{
implicit val variableWrites: Writes[Variable] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "content").write[String]
 )(unlift(Variable.unapply))
}

And then:

implicit val templateEmailMessageWrites: Writes[TemplateEmailMessage] = (
  (JsPath \ "to").write[List[EmailRecipient]] and
  (JsPath \ "global_merge_vars").write[List[Variable]]
)(unlift(TemplateEmailMessage.unapply))

Upvotes: 0

Related Questions