Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Scala Json Writer for Seq of Tuple

I'm trying to find a way to use the built in Macro Json Writer in order to serialize Seq[(String,Customer)]

I managed to do this for Seq[Customer] but when adding the touple, the compiler starts screaming at me.

This code works:

package models.health

import play.api.libs.json._

case class Customer(name: String, age: Int)

//we use the dummy var as a workaround to the json writer    limitations (cannot handle single argument case class)
case class Demo(customers: Seq[Customer], dummy: Option[String] =    None)

object Demo {

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

 implicit val customer_writer = Json.writes[Customer]

 implicit val writes: Writes[Demo] = (
 (__ \ "customers").write[Seq[Customer]] and
 (__ \ "dummy").writeNullable[String]) { 
    (d: Demo) => (d.customers,d.dummy)
 }

}

BUT the below code (simply change from Seq[Customer] to Seq[(String,Customer)] Doesn't Copmile... Any help is really appreciated:

package models.health

import play.api.libs.json._

case class Customer(name: String, age: Int)

//we use the dummy var as a workaround to the json writer    limitations (cannot handle single argument case class)
case class Demo(customers: Seq[(String,Customer], dummy: Option[String] =    None)

object Demo {

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

 implicit val customer_writer = Json.writes[Customer]

 implicit val writes: Writes[Demo] = (
 (__ \ "customers").write[Seq[(String,Customer)]] and
 (__ \ "dummy").writeNullable[String]) { 
    (d: Demo) => (d.customers,d.dummy)
 }

}

this is the compiler error I got:

No Json serializer found for type Seq[(String,models.health.Customer)]
like image 322
user1624010 Avatar asked Dec 20 '22 03:12

user1624010


1 Answers

The library makes no assumption as to how you want your tuple to serialize. You could use an array, an object, etc.

By adding this implicit Writes function, your serializer will write it out as an array.

  implicit def tuple2Writes[A, B](implicit a: Writes[A], b: Writes[B]): Writes[Tuple2[A, B]] = new Writes[Tuple2[A, B]] {
    def writes(tuple: Tuple2[A, B]) = JsArray(Seq(a.writes(tuple._1), b.writes(tuple._2)))
  }
like image 136
andyczerwonka Avatar answered Dec 24 '22 01:12

andyczerwonka