Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No Json formatter found Scala, Play framework error

I have following two implicits.

implicit val readObjectIdFormat = new Reads[ObjectId] {
def reads(jv: JsValue): JsResult[ObjectId] = {
  JsSuccess(new ObjectId(jv.as[String]))
 }
}

implicit val visitorFormat = (
(__ \ "_id").formatOpt[ObjectId] and
(__ \ "visitorId").format[String] and
(__ \ "referralUrl").formatOpt[String] and
(__ \ "ipAddress").formatOpt[String] and
(__ \ "promotionId").format[String])(Visitor)  

Though readObjectIdFormat is defined at compile time it keeps complaining following on "(__ \ "_id").formatOpt[ObjectId]" line

No Json formatter found for type org.bson.types.ObjectId. Try to implement an implicit Format for this type.

versions : Play 2.1-RC2, Scala 2.10

Any idea why it's not recognizing readObjectIdFormat ?

like image 687
Vikas Pandya Avatar asked Feb 05 '13 04:02

Vikas Pandya


2 Answers

Others gave the good answer, use Format instead. By the way, you could handle parse errors.

This implementation is working fine for me:

  implicit val objectIdFormat: Format[ObjectId] = new Format[ObjectId] {

    def reads(json: JsValue) = {
      json match {
        case jsString: JsString => {
          if ( ObjectId.isValid(jsString.value) ) JsSuccess(new ObjectId(jsString.value))
          else JsError("Invalid ObjectId")
        }
        case other => JsError("Can't parse json path as an ObjectId. Json content = " + other.toString())
      }
    }

    def writes(oId: ObjectId): JsValue = {
      JsString(oId.toString)
    }

  }
like image 51
Sebastien Lorber Avatar answered Sep 28 '22 00:09

Sebastien Lorber


You are implementing Reads and you need implement Format instead.

implicit val readObjectIdFormat = new Format[ObjectId] {
 def reads(jv: JsValue): JsResult[ObjectId] = {
  JsSuccess(new ObjectId(jv.as[String]))
 }

 def writes(o: A): JsValue = JsString(...)
}

Or you need to use the read instead of format (note I assume this works for read, haven't tested it).

implicit val visitorRead = (
(__ \ "_id").readOpt[ObjectId] and
(__ \ "visitorId").read[String] and
(__ \ "referralUrl").readOpt[String] and
(__ \ "ipAddress").readOpt[String] and
(__ \ "promotionId").read[String])(Visitor)  
like image 30
Ivan Meredith Avatar answered Sep 28 '22 00:09

Ivan Meredith