I have a mongo entry where one field is a list. If entry doesn't exist, I want to add new one. If it exists, I want to append a new element to the list.
At the end I want to return an Ok to the client, but only after the operation was completed successfully. Not a strict requirement, but it's what makes most sense for the user, in my opinion.
This is what I have currently - it works, but on update it overwrites the old list, instead of appending a new element.
def myMethod(value:String, value2:String) = Action {
Async {
val myElement = Json.obj(
"key" -> value2
)
val myDBEntry = Json.obj(
"key" -> value,
"list" -> List(myElement)
)
collection.update(Json.obj("key" -> value), myDBEntry, upsert = true).map(lastError =>
Ok("Mongo LastError: %s".format(lastError)))
}
}
In order to check if the list exists and append the element / create a new list, I started with something like (this replaces the collection.update
block in previous code):
val futureResult:Future[Option[JsObject]] = collection.find(Json.obj("key" -> value)).one[JsObject]
futureResult.map { result =>
if (result.isEmpty) {
collection.insert(myDBEntry).map(lastError =>
Ok("Mongo LastError: %s".format(lastError)))
} else {
//this not the correct command yet - but compiler already fails because method is not returning correct future
collection.update(Json.obj("key" -> value), myDBEntry, upsert = true).map(lastError =>
Ok("Mongo LastError: %s".format(lastError)))
}
}
But the compiler doesn't seem to like this nesting: "Type mismatch, expected: Future[Result], actual: Future:[Future[SimpleResult[Nothing]]]"
Anyways I feel this way is a bit awkward, and there must be a more elegant way to solve this, but I'm new to Futures and ReactiveMongo and have no idea. How do I solve it?
Edit: I also found this post But I think that's returning the response before the DB operation is finished and I don't want that.