summaryrefslogtreecommitdiff
path: root/book/src/main/scalatex/book/handson/ClientServer.scalatex
diff options
context:
space:
mode:
Diffstat (limited to 'book/src/main/scalatex/book/handson/ClientServer.scalatex')
-rw-r--r--book/src/main/scalatex/book/handson/ClientServer.scalatex27
1 files changed, 25 insertions, 2 deletions
diff --git a/book/src/main/scalatex/book/handson/ClientServer.scalatex b/book/src/main/scalatex/book/handson/ClientServer.scalatex
index 0a41dae..50afe76 100644
--- a/book/src/main/scalatex/book/handson/ClientServer.scalatex
+++ b/book/src/main/scalatex/book/handson/ClientServer.scalatex
@@ -1,3 +1,11 @@
+@import BookData._
+
+@def lazyload(id: String) = script(raw("""
+ document.addEventListener("load", function(){
+ document.getElementById(id).src = 'https://hands-on-scala-js.herokuapp.com/'
+ })
+"""))
+
@p
Historically, sharing code across client & server has been a holy-grail for web development. There are many things which have made it hard in the past:
@@ -38,7 +46,8 @@
@hl.ref("examples/crossBuilds/clientserver/build.sbt")
@p
- We have two projects: @code{client} and @code{server}, one of which is a Scala.js project (indicated by the presence of @hl.scala{scalaJSSettings}). Both projects share a number of settings: the presence of the @code{shared/} folder, which shared code can live in (similar to what we saw in @sect.ref{Cross Publishing Libraries}) and the settings to add @lnk.github.Scalatags and @lnk.github.uPickle to the build. Note that those two dependencies use the triple @code{%%%} instead of the double @code{%%} to declare: this means that for each dependency, we will pull in the Scala-JVM or Scala.js version depending on whether it's being used in a Scala.js project.
+ We have two projects: @code{client} and @code{server}, one of which is a Scala.js project (indicated by the presence of @hl.scala{scalaJSSettings}). Both projects share a number of settings: the presence of the @code{shared/} folder, which shared code can live in (similar to what we saw in @sect.ref{Cross Publishing Libraries}) and the settings to add @lnk.github.Scalatags and @lnk.github.uPickle to the build. Note that those two dependencies use the triple @code{%%%} instead of the double @code{%%} to declare: this means that for each dependency, we will pull in the Scala-JVM or Scala.js version depending on whether it's being used in a Scala.js project. Note also the @hl.scala{packageArchetype.java_application} setting, which isn't strictly necessary depending on what you want to do with the application, but this example needs it as part of the deployment to Heroku.
+
@p
The @code{client} subproject is uneventful, with a dependency on the by-now-familiar @code{scalajs-dom} library. The @code{server} project, on the other hand, is interesting: it contains the dependencies required for us to set up out Spray server, and one additional thing: we add the output of @code{fastOptJS} from the client to the @code{resources} on the server. This will allow the @code{server} to serve the compiled-javascript from our @code{client} project from its resources.
@@ -73,6 +82,13 @@
@p
Now, if we go to the browser at @code{localhost:8080}, we should see our web-page!
+ @iframe(id:="heroku1", width:="100%", height:="350px", "frameBorder".attr:="0")
+ @lazyload("heroku1")
+
+
+ @p
+ This is a real, live example running on a @lnk("Heroku server", "https://hands-on-scala-js.herokuapp.com/"). Feel free to poke around and explore the filesystem on the server, just to convince yourself that this actually works and is not just a mock up.
+
@sect{Client-Server Reflections}
@p
By now you've already set up your first client-server application. However, it might not be immediately clear what we've done and why it's interesting! Here are some points to consider.
@@ -206,7 +222,14 @@
While @hl.scala{Ajax.post} returned a @hl.scala{Future[dom.XMLHttpRequest]} and left us to call @hl.scala{upickle.read} and deserialize the data ourselves, @hl.scala{Ajaxer[Api].list(...).call()} now returns a @hl.scala{Future[Seq[FileData]]}! Thus we don't need to worry about making a mistake in the deserialization logic when we write it by hand.
@p
- Other than that, nothing much has changed. If you've done this correctly, the web application will look and behave exactly as it did earlier! So why did we do this in the first place?
+ Other than that, nothing much has changed. If you've done this correctly, the web application will look and behave exactly as it did earlier!
+
+ @iframe(id:="heroku2", width:="100%", height:="350px", "frameBorder".attr:="0")
+ @lazyload("heroku2")
+
+
+ @p
+ So why did we do this in the first place?
@sect{Why Autowire?}
@p