Search code examples
scalafunctional-programmingfuturescala-cats

Scala cats map EitherT Futures with key->value pairs


I'm a bit stuck, but maybe somebody can help me.

I have a list of id's I want to do an API call on:

val ids:List[String] = List("id1","id2","id3", "id4")

And this api method that returns a EitherT[Future, CustomError, JValue]

def recordById(id: String)(implicit ec: ExecutionContext): EitherT[Future, CustomError, JValue]

The code below works as I want: sequencing a list of futures to one future of list

val action:Future[List[Either[CustomError,JValue]]] = ids.map(
  id => api.recordById(id).value
).sequence

But what I really want is preserving the id's with the result, like:

val action2:Future[List[(String,Either[CustomError,JValue])]] = ids.map(
  id => (id, api.recordById(id).value)
).sequence

Solution

  • As I was typing the question. Something triggered and I've actually made it work using traverse instead of sequence

    val action2:Future[List[(String,Either[CustomError,JValue])]] = ids.map(
      id => (id, apiv4.recordById(id).value)
    ).traverse{
      case (id, etf) => etf.map(et => (id, et))
    }
    

    This seems to work as I wanted. I'm open to improvements /suggestions

    Edit:

    Suggestion by Marth

    ids.traverse(id => apiv4.recordById(id).value.map(id -> _))