Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json implicit format with recursive class definition

I have a recursive class defined :

case class SettingsRepository(id: Option[BSONObjectID],
                          name: Option[String],
                          children: Option[List[SettingsRepository]])

with a JSON implicit format as below :

implicit val repositoryFormat = Json.format[SettingsRepository]

How can I do to resolve this compilation error? :

No implicit format for Option[List[models.practice.SettingsRepository]] available.
In /path/to/the/file.scala:95

95 implicit val repositoryFormat = Json.format[SettingsRepository] 

I tried to define a lazy reads/write/format wrapper without any success... Anyone know a clean way to do that?

like image 904
Xan Avatar asked Jun 08 '15 14:06

Xan


1 Answers

As you've discovered, you can't use the JSON inception macro here, but you can write your own Format (note that I've replaced BSONObjectID with Long for the sake of a complete working example):

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

case class SettingsRepository(
  id: Option[Long],
  name: Option[String],
  children: Option[List[SettingsRepository]]
)

implicit val repositoryFormat: Format[SettingsRepository] = (
  (__ \ 'id).formatNullable[Long] and
  (__ \ 'name).formatNullable[String] and
  (__ \ 'children).lazyFormatNullable(implicitly[Format[List[SettingsRepository]]])
)(SettingsRepository.apply, unlift(SettingsRepository.unapply))

The trick is providing an explicit type annotation and using implicitly rather than just a type parameter on lazyFormatNullable.

like image 114
Travis Brown Avatar answered Nov 15 '22 12:11

Travis Brown