I have 3 futures of type Response. The first future returns a JsValue which defines if future 2 and future 3 shall be executed or only future 3 shall be executed.
Pseudocode: If Future 1 then {future2 and future 3} else future 3
Iam trying to do this in a play framwork action which means in order to use the result of the futures later I cant use onSuccess, onFailure and onComplete because all of them return Unit and not the actual JsValue from the last future.
I tried to do this with map() and andThen but I am a Scala noob and I guess i wasn't able to do it because I always just missed a little point. Here is my current approach which does not work!
def addSuggestion(indexName: String, suggestion: String) = Action.async {
val indexExistsQuery: IndexExistsQuery = new IndexExistsQuery(indexName);
val addSuggestionQuery: AddSuggestionQuery = new AddSuggestionQuery(indexName, suggestion)
val indexCreationQuery: CreateCompletionsFieldQuery = new CreateCompletionsFieldQuery(indexName)
val futureResponse: Future[Response] = for {
responseOne <- EsClient.execute(indexExistsQuery)
responseTwo <- EsClient.execute(indexCreationQuery) if (indexExistsQuery.getBooleanResult(indexExistsQuery.getResult(responseOne)))
responseThree <- EsClient.execute(addSuggestionQuery)
} yield responseThree
futureResponse.map { response =>
Ok("Feed title: " + (response.json))
}
I created some pseudocode:
checkIndexExists() map {
case true => Future.successful()
case false => createIndex()
} flatMap { _ =>
query()
}.map { response =>
Ok("Feed title: " + (response.json))
}.recover {
case _ => Ok("bla")
}
First you fire up the query if the index exists.
Then you map that future how to work with that Future[Boolean] if it successful. Since you use map, you kind of extract the Boolean. If the index exists, you just create a future that is already complete. If the index not exists you need to fire up the index creation command. Now you have the situation that you have nested Future's (Future[Future[Response]]). Using flatMap you remove one dimension, so that you only have Future[Response]. That can be mapped to a Play result.
Update (the implementation of MeiSign):
EsClient.execute(indexExistsQuery) map { response =>
if (indexExistsQuery.getBooleanResult(indexExistsQuery.getResult(response))) Future.successful(Response)
else EsClient.execute(indexCreationQuery)
} flatMap { _ =>
EsClient.execute(addSuggestionQuery)
} map { response: Response =>
Ok("Feed title: " + (response.json))
}
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