summaryrefslogtreecommitdiff
path: root/examples/demos/src/main/scala/advanced/Futures.scala
blob: 0d7107d71c8347692509eed403769b85e9147749 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package advanced

import org.scalajs.dom
import org.scalajs.dom.XMLHttpRequest
import org.scalajs.dom.extensions.{Ajax, KeyCode}
import scala.collection.mutable
import scala.concurrent.Future
import scala.scalajs.js
import scalatags.JsDom.all._
import scala.scalajs.js.annotation.JSExport
import scala.scalajs.concurrent.JSExecutionContext.Implicits.runNow
@JSExport
object Futures {
  def main(container: dom.HTMLDivElement,
            handle: (Seq[String], dom.HTMLDivElement) => Unit) = {
    val myInput = input(value:="London,Singapore,Berlin,New York").render
    val output = div.render
    myInput.onkeyup = (e: dom.KeyboardEvent) => {
      if (e.keyCode == KeyCode.enter){
        handle(myInput.value.split(','), output)
      }
    }
    container.appendChild(
      div(
        i("Press Enter in the box to fetch temperatures "),
        myInput,
        output
      ).render
    )
  }
  def urlFor(name: String) = {
    "http://api.openweathermap.org/data/" +
    "2.5/find?mode=json&q=" +
    name
  }
  def parseTemp(text: String) = {
    val data = js.JSON.parse(text)
    val kelvins = data.list
                      .pop()
                      .main
                      .temp
                      .asInstanceOf[Double]
    kelvins - 272.15
  }
  def formatResults(output: dom.HTMLElement, results: Seq[(String, Double)]) = {
    output.innerHTML = ""
    output.appendChild(ul(
      for((name, temp) <- results) yield li(
        b(name), " - ", temp.toInt, "C"
      )
    ).render)
  }
  @JSExport
  def main0(container: dom.HTMLDivElement) = {
    def handle0(names: Seq[String], output: dom.HTMLDivElement) = {
      val results = mutable.Buffer.empty[(String, Double)]
      for(name <- names){
        val xhr = new XMLHttpRequest
        xhr.open("GET", urlFor(name))
        xhr.onload = (e: dom.Event) => {
          val temp = parseTemp(xhr.responseText)
          results.append((name, temp))
          if (results.length == names.length){
            formatResults(output, results)
          }
        }
        xhr.send()
      }
    }
    main(container, handle0)
  }
  @JSExport
  def main1(container: dom.HTMLDivElement) = {
    def handle1(names: Seq[String], output: dom.HTMLDivElement) = {
      val results = mutable.Buffer.empty[(String, Double)]
      for{
        name <- names
        xhr <- Ajax.get(urlFor(name))
      } {
        val temp = parseTemp(xhr.responseText)
        results.append((name, temp))
        if (results.length == names.length){
          formatResults(output, results)
        }
      }
    }
    main(container, handle1)
  }
  @JSExport
  def main2(container: dom.HTMLDivElement) = {
    def handle2(names: Seq[String], output: dom.HTMLDivElement) = {
      val futures = for(name <- names) yield{
        Ajax.get(urlFor(name)).map( xhr =>
          (name, parseTemp(xhr.responseText))
        )
      }

      for(results <- Future.sequence(futures)){
        formatResults(output, results)
      }
    }

    main(container, handle2)
  }


}