Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala how to convert future of one type to future of another type

Tags:

scala

i have a function which retrieve data from DB and return type of Future[ResponseDTO], then I need to convert it to Future of HttpResponse

my code:

val responseDTO = database.getResponseDto(service) => Future[ResponseDTO]

responseDTO.onComplete {
   case Success(responseDTO) => HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload)
   case Failure(exception) => HttpError("error")
}

it wont work

tried this one too, still don't work

responseDTO.map(
  dto => EitherT.pure[Future, HttpError](HttpResponse(status = dto.responseCode, entity = dto.responsePayload))
)
like image 584
user468587 Avatar asked May 10 '19 23:05

user468587


People also ask

How do you handle Future Scala?

Handle the result of a future with methods like onComplete , or combinator methods like map , flatMap , filter , andThen , etc. The value in a Future is always an instance of one of the Try types: Success or Failure.

What does Future successful do Scala?

Future. successful is designed for immediately inserting a result that you've precomputed. If you put some blocking code in there instead of a value, it'll block at that point in your current thread.

What is await result in Scala?

Await. result tries to return the Future result as soon as possible and throws an exception if the Future fails with an exception while Await. ready returns the completed Future from which the result (Success or Failure) can safely be extracted.


2 Answers

Using transform should give the answer you want:

responseDTO.transform {
  case Success(responseDTO) => Success(HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload))
  case _ => Success(HttpError("error"))
}

This will return a successful Future whose result type is compatible with both HttpResponse and HttpError.

If you want to retain the information about success/failure it is best to do this by using the status of the Future. In that case your code would use an alternate version of transform, like this:

case class HttpErrorException(err: HttpError) extends Throwable

responseDTO.transform(
  responseDTO => HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload),
  _ => HttpErrorException(HttpError("error"))
)

You can then use the Future methods in the rest of the code to extract the HttpResponse or HttpErrorException when required.

like image 100
Tim Avatar answered Sep 20 '22 15:09

Tim


You want to map the future. The .onComplete method doesn't transform the future, just adds an handler (useful for side effects)

responseDTO.map(dto => HttpResponse(status=dto.responseCode, entity=dto.responsePayload))
like image 28
pedrorijo91 Avatar answered Sep 22 '22 15:09

pedrorijo91