Json implicit format with recursive class definition

I have a recursive class:

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

with implicit JSON format as shown below:

 implicit val repositoryFormat = Json.format[SettingsRepository] 

How can I do this to solve 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 defining the lazy reads / write / format wrapper without any success ... Does anyone know how to do this?

Any help would be appreciated

Thanks in advance.

+5
source share
2 answers

As you discovered, you cannot use a macro to create JSON, but you can write your own Format (note that I replaced BSONObjectID with Long for the full work 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 provides explicit type annotation and use implicitly , not just the type parameter on lazyFormatNullable .

+6
source

For others who came here looking for a small option where we override reads and writes in the Format class (for example, the example specified in the API docs), you can declare a lazy link to your desired object:

  lazy val tweetFormat: Format[Tweet] = TweetFormat implicit object UserFormat extends Format[User] { //... } //... implicit object TweetFormat extends Format[Tweet] { //... 
0
source

All Articles