0

In a play-scala application, Im making a WS call:

def getaddresses : ListBuffer[String] = {
   var lb = new ListBuffer[String]()
   var url = "xyz@xyx.com/someapi"

   WS.url(url).get.map {
      response =>
        var emailsSeq = (response.json \\ "email")
        emailsSeq.foreach(lb+=_.toString())
        lb.foreach(println)     //This is filled with values
  }
  lb.foreach(println)           //This is empty
  lb
}

Inside map a sequence is returned whose entries I put in a ListBuffer lb to be returned by this method. The problem is that the the ListBuffer shows values inside map{} but does not show outside it. As a result empty ListBuffer is passed from the method.

I thought there might be a delay in ws response so tried the following which had no advantage:

WS.url(url).withRequestTimeout(10.seconds).get.map {

Please help me in getting filled list buffer to be returned

surm
  • 167
  • 2
  • 11

1 Answers1

0

I think that ws.url(url).get method is async, so when you call lb.foreach(println), there is nothing to print. Try to add Thread.sleep just after map block of code. If it is so, you should make getaddresses method async, or use future/promise.

PS: you should use val instead of var, just for cleaner code.

EDIT: Sample to try:

def getaddresses : ListBuffer[String] = {
   val url = "xyz@xyx.com/someapi"

   val promiseOfAddresses = Promise[ListBuffer[String]]()
   WS.url(url).get.map {
      response =>
        var emailsSeq = (response.json \\ "email")
        promiseOfAddresses.success(emailsSeq) // here you will complete promise with actual value
  }
  val lb = promiseOfAddresses.future.get // here you will obtain future from promise and also get value of future. Method get is blocking and it will wait till promise is fullfiled or failed
  lb.foreach(println)           //This is empty
  lb
}

PS2: Probably best help with future/promises can be found here: the-neophytes-guide-to-scala-part-9-promises-and-futures-in-practice (I have not enough reputation, so google this blog) It is something like CompletableFuture in java world. But remember, that best way is to stay all time in red side (red = asynchronous functions/methods. see nice, but chatty, blog what-color-is-your-function)

Lubomir Varga
  • 109
  • 2
  • 8
  • thanks for your reply. lb.foreach(println) is getting printed inside the map block. So I think the call is not getting delayed but how do I get that value outside the map block to pass to getaddress's caller. – surm Jul 13 '16 at 12:42
  • As I have said, you can try to use future for example. Have a look at http://alvinalexander.com/scala/future-example-scala-cookbook-oncomplete-callback or try this simple code which I add to my answer. – Lubomir Varga Jul 15 '16 at 05:15