I'm using json4s
for dealing with Json responses from http responses. I was earlier using Await
but I'm now switching to use Future
.
I have a function like:
executeRequest(): Future[Response[String]]
and another function like:
def getAccessToken() = {
executeRequest().map {
response: Response[String] => // read method in the next line cannot be resolved
read[AccessTokenResponse](response.body).access_token
}
// the following line is ok
read[AccessTokenResponse]("{\"access_token\":\"fake_token\"}").access_token
}
Now, the read
inside the map
block is no longer recognized/found by my IntelliJ which I'm assuming means I'm doing something wrong. But the read
outside of the map
block resolves correctly.
What am I doing incorrectly here? I'm new to Scala :/
Compiler output:
overloaded method value read with alternatives:
(in: java.io.Reader)(implicit formats: org.json4s.Formats, implicit mf: scala.reflect.Manifest[AccessTokenResponse])AccessTokenResponse <and>
(json: org.json4s.JsonInput)(implicit formats: org.json4s.Formats, implicit mf: scala.reflect.Manifest[AccessTokenResponse])AccessTokenResponse <and>
(json: String)(implicit formats: org.json4s.Formats, implicit mf: scala.reflect.Manifest[AccessTokenResponse])AccessTokenResponse
cannot be applied to (Either[String,String])
read[AccessTokenResponse](response.body).access_token
The error which you are getting means that the read
method can accept an argument of one of these types:
java.io.Reader
org.json4s.JsonInput
String
This line works because you are passing a String
to read
:
read[AccessTokenResponse]("{\"access_token\":\"fake_token\"}").access_token
However, as we can see from the error message, the response.body
type is Either[String,String]
.
Either
is a sum type with two variants: Left
and Right
. Basically, that means that when a method returns Either[A, B]
, the actual result can be either A
or B
wrapped into Left
or Right
respectively.
Either
is often used to represent a result of an operation which can fail, where Left
is returned in case of an error while Right
contains the result of the operation in case of success. If this is the case, you might want to pattern match on the result to extract the value:
executeRequest().map { response =>
response.body match {
case Right(body) =>
read[AccessTokenResponse](body).access_token
case Left(err) =>
// Handle the error here
}
}