The arguments to Json.obj repeated (String, JsValueWrapper) s. When you pass some variable, the compiler will try to implicitly convert your type to JsValueWrapper using the transforms defined in the Play JSON library (or Writes for your types).
The problem here is the contravariance of getOrElse . Since the signature of getOrElse is this:
def getOrElse[B >: A](default: ⇒ B): B
This means that if you have Option[String] , you can specify a value of getOrElse that is not String , and Option[String] will most likely become Option[Any] . Because of this feature, the compiler does not look for implicit conversion in JsValueWrapper , and it does not work.
The problem goes away if you use fold in Option , which is invariant:
scala> val testVal = Some("foo") testVal: Some[String] = Some(foo) scala> Json.obj("myJson" -> testVal.fold("")(identity)) res7: play.api.libs.json.JsObject = {"myJson":"foo"}
source share