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 ?
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)
}
}
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With