xtiger
xtiger

Reputation: 1446

Map data from a Scala Future

I'm implementing a task to calling to some Rest Endpoint in Play Framework, here's the code in my Service:

override def getAccessToken(loginData: LoginData): Future[Unit] = {
    logger.info("get access token from HAT")
    val accessTokenURL = // This is the URL to be called
    logger.info(accessTokenURL)
    ws
      .url(accessTokenURL)
      .withHttpHeaders(
        HeaderNames.ACCEPT -> ContentTypes.JSON,
        "username" -> loginData.username,
        "password" -> loginData.password
      )
      .withRequestTimeout(timeout)
      .get()
      .map {
        response => response.status match {
          case Status.OK =>
            val responseAsJson = response.json
            Future.successful((responseAsJson \ "accessToken").as[String])

          case _ =>
            val message = (response.json \"message").asOpt[String]
            throw new GeneralBadRequestException(message.get)
        }

      }
  }

The response of the val accessTokenURL will be something like:

{
    "accessToken": "some token",
    "userId": "some user id"
}

Then in my controller, I write some function like this to get the data from the Service above:

  private def handleAccessToken: LoginData => Future[Result] = { loginData =>

    requestHATService.getAccessToken(loginData).map (
      response => Ok(response)) recover {
      case e =>
        val errorJson: JsValue = Json.obj(
          "status" -> "ERROR",
          "error" -> Json.obj(
            "code" -> "ERROR",
            "message" -> e.getMessage
          )
        )
        BadRequest(errorJson)
    }
  }

What I'm struggling at this moment is the part response => Ok(response)) in the function handleAccessToken, I want to include it to the Ok Result to return in controller response but I can not get the data out, especially the accessToken, when I'm trying to compile the code , an error throw like this:

Cannot write an instance of Unit to HTTP response. Try to define a Writeable[Unit]

Edit : Thanks to @Frederic for the answer, I have another problem here, how can I attach the response string to some JsValue and pass to Ok Result, some thing like

  val successJson: JsValue = Json.obj("status" -> "OK")
    requestHATService.getAccessToken(loginData).map (
      response => 
            // code to attach response to successJson here 
            Ok(successJson)) recover {
                 ......
            }

Upvotes: 0

Views: 92

Answers (1)

Frederic A.
Frederic A.

Reputation: 3514

The problem is in the definition of: def getAccessToken(loginData: LoginData): Future[Unit]

It should be: def getAccessToken(loginData: LoginData): Future[String]

Do you need more explanations?

Upvotes: 1

Related Questions