Frage

I am following play-salat (github.com/leon/play-salat) to create a model for a json input and save to mongodb. How can I create the implicit json read for List collection which might be missing in the input json? The following code gives me the validation error if the 'positions' is missing from input json.

case class LIProfile(
  id: ObjectId = new ObjectId,
  positions: List[Position] = Nil
)

object LIProfile extends LIProfileDAO with LIProfileJson

trait LIProfileDAO extends ModelCompanion[LIProfile, ObjectId] {
  def collection = mongoCollection("liprofiles")
  val dao = new SalatDAO[LIProfile, ObjectId](collection) {}

  // Indexes
  collection.ensureIndex(DBObject("emailAddress" -> 1), "li_profile_email", unique = true)

  // Queries
  def findOneByEmail(email: String): Option[LIProfile] = dao.findOne(MongoDBObject("emailAddress" -> email))
}


trait LIProfileJson {

  implicit val liprofileJsonWrite = new Writes[LIProfile] {
    def writes(p: LIProfile): JsValue = {
      Json.obj(
        "id" -> p.id,
        "positions" -> p.positions
      )
    }
  }
  implicit val liprofileJsonRead = (
    (__ \ 'id).read[ObjectId] ~
    (__ \ 'positions).read (
            (__ \ 'values).read[List[Position]]
            ) 
  )(LIProfile.apply _)
}
War es hilfreich?

Lösung

Use readNullable in order to retrieve an Option and map that to the contained list or the empty list.

implicit val liprofileJsonRead = (
  (__ \ 'id).read[ObjectId] ~
  (__ \ 'positions).readNullable (
    (__ \ 'values).read[List[Position]]
  ).map {
    case Some(l) => l
    case None => Nil
  }
)(LIProfile)

or even shorter:

implicit val liprofileJsonRead = (
  (__ \ 'id).read[ObjectId] ~
  (__ \ 'positions).readNullable (
    (__ \ 'values).read[List[Position]]
  ).map { l => l.getOrElse(Nil) }
)(LIProfile)

I'm not quite sure what imports you really need here, my code compiles using:

import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top