Programmation appliquée en Scala

Copyright © Cay S. Horstmann 2015 Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License

Lab

Scary looking lab

Part 1: Getting Started with Play

  1. Download the “Typesafe Activator” from this site
  2. Unzip into your home directory
  3. Make sure java is on the PATH. Open a command shell. Type
    javac -version
    You should be getting something like javac 1.8.0_31. If not, follow these directions.
  4. In a command shell, type

    activator-1.3.2/activator new
    (adjusting the directory path and version number if necessary) Select the play-scala option from the menu, then give unit15 as application name.

  5. Type
    cd unit15
    activator-1.3.2/activator
    (without new)! You are now getting a prompt in the Activator shell. Type
    ~run
    Point your browser to localhost:9000. What happens?

Part 2: The App Layout

  1. In the Activator shell window, hit Ctrl+D to get back to the prompt. Type
    eclipse
  2. Start the Scala IDE. Select File → Import → Existing Projects into Workspace, and navigate to the unit15 directory. Select Finish.
  3. In the Activator shell window, type
    ~run
    (note the ~).
  4. If you get an error in Application.scala, select Project -> Properties -> Java Build Path -> Source and add the directories unit15/target/scala-2.11/src_managed/main and unit15/target/scala-2.11/twirl/main to the source folders (see this post)
  5. In index.scala.html, replace the code inside { } with
    Hello @message
    Save and reload the localhost:9000 page. What happened?
  6. Go to Application.scala and change "Your application is ready" to "Unit 15". Save and reload the localhost:9000 page. What happened?
  7. Point your browser to http://localhost:9000/assets/images/favicon.png. What happens? Why? (Hint: conf/routes)
  8. Ok, now we are ready for the lecture.

Web Applications

Web Application Frameworks

Web Application Framework Trends

Play Framework

Controllers

Futures

Routes

Templates

Forms

Form Helpers

Persistence

Anorm Result Set Parsing

Lab

  1. We'll set up a very simple to do list, following this tutorial. Play has changed a little since then, so the first part no longer applies. Instead, we continue with the lab, as set up in the first part, and join the tutorial at the section "Preparing the application"
  2. Go ahead and edit conf/routes and described, and check the compile-time error that tells you the routes error.
  3. Add the definitions to Application and verify the TODO behavior.

Forms

  1. Make a package models inside app and define the Task class as specified.
  2. Set up the index.scala.html page, task form, and the tasks action as described. Make sure that http://localhost:9000/tasks looks like in the tutorial in the section "Rendering the first page".
    Then look at the index.scala.html page. What parameters does the page have? Where do they come from? (That is, who supplies them?) What happens with the first parameter? With the second?
  3. What happens when you submit the form? Why? Which method do you need to implement to fix this?
  4. Follow the step "Handling the form submission". Check out Form in the Play API. What is the significance of bindFromRequest? Explain the syntax of the stuff inside fold(...).

Queries

  1. Now follow “Persist the tasks in a database”. Uncomment the four lines in conf/application.conf that start with db.default. Make the file conf/evolutions/default/1.sql (and be careful that you use exactly that path—otherwise, it won't work). Verify that you get the evolution screen, and click Apply.
  2. Now start implementing the SQL queries. First, provide the task parser. Which class does it go into?
  3. You've seen something just like that in Unit 12, except for map. What was it called there?

Implicits

  1. Paste in the all method. That's a lot of strange syntax. We haven't covered implicit yet, except for implicitly in Unit 9. The idea is that a parameter labeled implicit is set to the unique object of the appropriate type that has been defined as implicit. Let's start figuring this out. What is DB? (Look it up in the Play API.)
  2. There are two methods called withConnection. Which one are we calling?
  3. Now click on the link DB.scala on the top of the API. Find the source code of that method. Note it refers to a function db. What type does that function return?
  4. That type has a function database. What type does it return?
  5. And that type has a perfectly normal function
     def withConnection[A](block: (Connection) ⇒ A): A
    Click on Database.scala and read the implementation (it's in DefaultDatabase). If you've ever done JDBC programming, this is straightforward:
    1. Get a connection
    2. In a try/finally block, run code that uses it
    3. In the finally clause, close the connection
  6. We did all that because we wanted to follow the implicit. Start again with DB.withTransaction. Notice the last (curried) parameter. It is declared as implicit. That means, an object is silently passed to this function whenever it is called. What is the type of that object?
  7. Now follow the call to db. What happens to that special object?
  8. How did the Application object get in there in the first place? We can't (easily) answer that, but we can look at how another object is passed as an implicit object. Let's go back to
    def all(): List[Task] = DB.withConnection { implicit c =>
      SQL("select * from task").as(task *)
    }
    Ignoring the implicit for a minute, recall what happens here. A connection was found, and block(connection) was called. That's just a normal function call. To see why c is implicit, we need to look further. Mouse over the as method in Eclipse. What do you get?
  9. Note the second, implicit parameter. When as gets called, it wants some connection. Which one is it going to get?

Finishing Up

  1. Enough of implicit objects. Let's solve a different mystery. What is the * behind task? Hint: Mouse over it.
  2. Finally, add the create and delete methods. Run the app and create a few tasks.
  3. What happens when you try to delete one?
  4. Fix that and try out that everything works now. Stop before "Deploying to Heroku"
  5. Finally, have another look at create and delete. Notice the curious 'label and 'id. Those are Scala symbols—kind of like strings, but different. Replace them with "label" and "id", and verify that you can still create and delete tasks.

Homework

Sadly, we have reached the end of the rope with Codecheck. In this homework assignment, you will write a simple Play application. Zip up the entire directory and email it to Prof. Borran when you are done. Also, be prepared to demo your solution during the next class meeting.

Write a web app that can be used for online “clickers”, rather than the paper index cards that we have used in class. Here is the workflow.

  1. The professor visits quiz/new and enters the question and four answer choices [Extra credit for variable numbers of choices]. When the professor hits submit, a number is displayed (just show the ID number in the database)
  2. The professor announces the ID number to the students.
  3. The students visit quiz/reply/id (with that ID) and select an answer
  4. Afterwards, the professor visits quiz/results/id, and the number of responses for each choice is displayed.

Tip: If you want to make the app look prettier (and also for general hints), run activator new computer-database-scala and have a look at the resulting app.