Wednesday 4 September 2013

Building an assessment app in two days -- 6th commit

After a long pause while I fixed that bug, back to getting the app up and running.

The sixth commit has basic sign-in, sign-up, and sign-out functionality working, which means we have our first proper controller on the server and our first proper service on the client.

Earlier I said I wasn't going put in email/password log in. Well, I then realised I would need to.

Later on, I'm going to need to try out creating a course (as staff) and then preenrolling a different user (as a student). That means I need two accounts, but I only have one GitHub log in.

Handling users on the server

UserController contains the various concise actions that we've defined on the server:

  • self to return JSON for the currenlty logged in user
  • signUp to sign up
  • logIn to log in
  • logOut to log out.

At the top of the controller, there is the interesting line

implicit val userToJson = UserToJson

This is used to convert the responses to JSON format.

If you then have a look at UserToJson, you'll see it's a slightly different strategy for converting to JSON than most libraries. The key function is:

def toJsonFor(u:User, a:Approval[User]) = { 
  // etc

This is from recognising that very often we want to give different information depending on who's asking. For instance, in this case we only want to give out the JSON data for the user if they are asking about themselves, not someone else.

And, it returns a Ref[JsValue] rather than just a JsValue, in case it has any other work it needs to do before it can return a result.

Handling users on the client

UserService is the corresponding component on the client. Again, it has self, signUp, logIn, and logOut actions which are all neatly concise.

Angular.js has built into it promises. These are very much like the way Promises and Futures work in Scala on the server.

Which is perhaps why I quite like working with Angular.js in the browser!

No comments: