Reputation: 555
I would like to make nested asynchronous calls. I would like to perform one async call before I make a 2nd async call. The 1st async call will dictate what parameters or actions to take with the 2nd async call.
Here's the original async call:
def render(param1:String) = Action.async { request =>
implicit val ctx = RequestContext.createFromRequest(request)
Page.load(param1, request).map {
case PageType1(title) =>
Ok(views.html.main("pageType1", title))
case PageType2(title) =>
Ok(views.html.main("pageType2", title))
}
}
The async I would like to perform before the Page.load() async call would asynchronously validate the signed in user's info. If the user is not signed in, then an unauthenticated anonymous token is created. This info needs to be written to an array of cookies which is the return value of the async getAuthCookies() method, see sample code below. These cookies need to be added to the Ok() method using the withCookies() method. (Eventually I could also change the flow of the code depending on what info is gathered in the getAuthCookies() method so a user sign-in page is created if the user's session has expired.) This is probably more background info on the code that is necessary, but hopefully the general code examples are good enough to give you an idea of what I am trying to do.
See below for the async call to the getAuthCookies() method:
...
implicit val ctx = RequestContext.createFromRequest(request)
for {
cookies <- Authenticator.getAuthCookies(request)
} yield {
//Placing Page.load() here doesn't work. It produces a type mismatch err
}
...
I've tried to place the Page.load() code within the yield statement, but it produces a type mismatch error within the more general render() method.
How can I ensure the the Page.load() async method is called after the Authenticator.getAuthCookies() async method but ensure a type mismatch error is not produced?
Upvotes: 1
Views: 207
Reputation: 1086
Put the next async call (Future) inside the for comprehension. This way you can chain the calls. Let's say that Page.load()
returns Future[Page]
, in the code below the page
value will be Page
not Future[Page]
. This way Page.load()
is called after the getAuthCookies
method.
...
implicit val ctx = RequestContext.createFromRequest(request)
for {
cookies <- Authenticator.getAuthCookies(request)
page <- Page.load()
} yield {
}
...
Also note, for comprehensions are just syntactic sugar for flatMap
operations. I good introduction to Futures can be found here:
Upvotes: 1