1

I'm using Play 2.5 with Scala, I created a class that will call multiple times external web services.

External web services are called on some condition and get a simple response of ok or nok. If it is ok then I should update internal objects status and if nok I do nothing for now.

Here is my class, it takes a list of list of String as paramters and return a Future list of object to be handled in the controller.

def callWSAndGetResponse(listOfList: List[List[String]]): Future[List[MyObject]] = {

    val res = listOfList map { listOfIds =>
        listOfIds map { id =>
            val foundObj = allMyObject.find(obj => obj.id == id)
            if(foundObj.isDefined) {
                foundObj.get.urls map { url =>
                    val futureReponse: Future[WSResponse] = ws.url(url).get()

                    futureResponse map { response =>
                        (response.json \ "response").as[String]
                    }
                }
            }
        }

    }

    // if responses are ok create a list of MyObject to return for example.


}

val res is of type list of list but I would like it to be just a simple list of response.
1) How to simplify and correct my code in order to get just a list of response, for later check if ok or not ?

2) How to check if responses are ok or have failed ?

jerome
  • 2,029
  • 4
  • 38
  • 58

1 Answers1

0

It looks like you want this block to return a List[Future[Json]], from then you can use "List[Future] to Future[List] disregarding failed futures" or similar.

To do this you should use map and flatMap (rather than isDefined/get):

val res = listOfList map {
    _.map { id =>
        allMyObject
            .find(obj => obj.id == id)
            .map {
                _.flatMap {url =>
                    val futureReponse: Future[WSResponse] = ws.url(url).get()
                    futureResponse map { response =>
                        (response.json \ "response").as[String]
                }
            }
        }
    }
}

if blocks assign to AnyVal rather than to a specific type (which will cause you issues here):

scala> if (true) 23
23: AnyVal

scala> if (false) 23
(): AnyVal

Using map keeps you in the Option monad:

scala> (None: Option[Int]).map(_ * 2)
None: Option[Int]
Community
  • 1
  • 1
Andy Hayden
  • 359,921
  • 101
  • 625
  • 535