Wisnu Wardoyo
Wisnu Wardoyo

Reputation: 25

Scala, change variable value inside Future

I have code below :

          val trxRequest: WSRequest = ws.url(route.transcationRoutes).withHeaders("Accept" -> "application/json")
          val futureResponse: Future[WSResponse] = trxRequest.post(Json.obj("trxtype" -> trxType, "trxvariable" -> trxVariable, "account" -> account.toJson))
          var responseStatus = 0 // I want to change this variable value
          futureResponse.map {
            response => {
              logkey = (LoginKeyUtils.getEncryptedKey(accountId))
              session.addSession(accountId -> logkey)

              responseStatus = response.status // I change it here

              println(responseStatus) // variable changed

              }

          }
          Ok(responseStatus +"") //But here back to 0 again

I want to change responseStatus value. It's value changed inside map {}, but back to 0 again when outside map. Is there something wrong? I'm newbie.

@Mikel, Thank you this is the solution,

          val trxRequest: WSRequest = ws.url(route.transcationRoutes).withHeaders("Accept" -> "application/json")
          val futureResponse: Future[WSResponse] = trxRequest.post(Json.obj("trxtype" -> trxType, "trxvariable" -> trxVariable, "account" -> account.toJson))
          var responseStatus = 0
          //Need to retrieve as future
          val futureResult: Future[Any] = futureResponse.map {
            response => {
              logkey = (LoginKeyUtils.getEncryptedKey(accountId))
              session.addSession(accountId -> logkey)
              responseStatus = response.status;
              println(responseStatus)

            }
          }
          // wait for the result
          Await.result(futureResult, 5000 millis)
          Ok(responseStatus)

Upvotes: 1

Views: 1103

Answers (2)

jilen
jilen

Reputation: 5763

You should avoid use Await here.

Could simplily be

Action.async {
  ...
  futureResponse.map { r =>
    Ok(r.status + "")
  }
}

Action.async takes an Future[Result] as the http response

Upvotes: 0

Mikel San Vicente
Mikel San Vicente

Reputation: 3863

The future is executed asynchronously, so there are a lot of chances that Ok(responseStatus +"") is executed before the variable has been modified.

If you want to be sure that the future has been executed you can add this before the last line

import scala.concurrent.{Await, Future}
import scala.concurrent.duration._    
Await.result(futureResponse, 5000 millis)

But in your case I guess what you need to do is retrieving the response as a Future

val trxRequest: WSRequest = ws.url(route.transcationRoutes).withHeaders("Accept" -> "application/json")
val futureResponse: Future[WSResponse] = trxRequest.post(Json.obj("trxtype" -> trxType, "trxvariable" -> trxVariable, "account" -> account.toJson))
var responseStatus = 0 // I want to change this variable value
futureResponse.map {
    response => {
        logkey = (LoginKeyUtils.getEncryptedKey(accountId))
        session.addSession(accountId -> logkey)

        responseStatus = response.status // I change it here

        println(responseStatus) // variable changed
        Ok(responseStatus +"")
    }
}

Upvotes: 1

Related Questions