5
\$\begingroup\$

I have the following Scala code:

  def getLists(token: String, username: String):Future[Try[Seq[Group]]] = {
    val result:Future[Try[JsValue]] = getAPIResult(token, "https://myapi.com/screen_name=" + username)
    result.map( x => convertFromJsValueToObject(x))
  }

  def getSubscriptions(token: String, username: String):Future[Try[Seq[Group]]] = {...} //same as above

  private def getAPIResult(token: String, apiCall: String):Future[Try[JsValue]] = {
    WS.url(apiCall)
    .withHeaders("Authorization" -> ("Bearer " + token))
    .get().map(response =>
       response.status match {
       case 200 => Success(Json.parse(response.body))
       case _ => Failure(new RuntimeException("Web service call failed: " + response.body))
    })
  }

  private def convertFromJsValueToObject(json: Try[JsValue]): Try[Seq[Group]] = {
    json match {
      case Success(v) => {
        Success(v.as[Seq[Group]])
      }
      case Failure(t) => Failure(t)
      }
  }

and I have a third function like this:

def getAllListsAndSubscriptions(token: String, username: String):Future[Try[Seq[Group]]] = {...}

Which is supposed to concatenate the two Seq collections of Group objects together and return them as per the type signature. I'm really struggling to figure out how to do this though, as the types are so deeply nested.

Have I written my code badly or is there another way to do this?

\$\endgroup\$
3
\$\begingroup\$

You should "lift" your functions instead.

For example, instead of defining:

def getSomething(input: V): Future[FinalType] = {
   val intermediate: IntermediaryType = complicatedFunctionReturningFuture(input)
   mappingFunction(intermediate)
}

use

complicatedFunctionReturningFuture(input).map(mappingFunction)

directly in your code.

You can think of map as a method that is lifting a function IntermediaryType => FinalType to a function Future[Intermediary] => Future[FinalType].

If you have a Future[Try[Type]], you can do a "double lifting" (I'm claiming the trademark on that term!):

complicatedFunctionReturningFutureTry(input).map(_.map(mappingFunction))

which lifts the same function IntermediaryType => FinalType to a function Future[Try[Intermediary]] => Future[Try[FinalType]].

\$\endgroup\$
  • \$\begingroup\$ Also as a shortcut it might make sense to use for comprehension. \$\endgroup\$ – n1ckolas Sep 4 '14 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.