Reputation: 9734
The following find
method should return any document that matches the specified selection criteria and in case sort them as specified by optional parameter sort
:
class DaoComponent {
...
val toObjectId = (__.json.update((__ \ '_id \ '$oid).json.copyFrom((__ \ 'id).json.pick))
andThen (__ \ 'id).json.prune
)
...
def find(selector: JsValue, sort: Option[JsValue]): Future[Seq[A]] = {
selector.transform(toObjectId).flatMap { s =>
sort.map(_.transform((__ \ 'ignore).json.prune)).map { o =>
// how do I get 'o' to be either None or Some(content of JsSuccess)?
collection.find(s)
.sort(o.getOrElse(Json.obj())
.cursor[JsValue].collect[Vector](0)
}.recoverTotal { errors =>
Future.failed(JsError.toFlatJson(errors))
}
}
}
In the code above, let's isolate the line where I need your valuable support:
sort.map(_.transform((__ \ 'ignore).json.prune)).map { o =>
Optional parameter sort
has to be transformed only if defined... and this is achieved with map
. Now the problem is that transform
returns a JsResult
, and I want o
to be either Some(jsValue)
when optional parameter sort
is defined and transform
succeeds, or None
when transform
fails or optional parameter sort
is not defined.
Alternatively, instead of getting None
when _.transform
fails, it would be great if I could handle the failure in the recoverTotal
block.
Upvotes: 0
Views: 564
Reputation: 10007
Expanding on my comment -
I think that the right combination of flatMap
and converting your JsResult asOpt
will get what you want:
sort.flatMap(_.transform((__ \ 'ignore).json.prune).asOpt).map { o =>
// Code in here only executed iff sort defined and transform succeeds
...
}
BTW in my tests I couldn't actually get transform
to "fail" in this case - I think prune
is quite tolerant if the given JSON is not present. I could get it to fail appropriately like this:
sort.flatMap(_.transform((__ \ 'ignore).json.pick).asOpt).map { o =>
Upvotes: 1