Play 2.1 Grunt, Angular - Prototype - Image

Play 2.1 Grunt, Angular - Prototype

Play Framework

I’ve done a Play 2.1 Grunt / Angular prototype that I’d like to share with you.

Preface

Being able to run grunt side by side with play is an awesome setup. Using Less or compass without sluggish rhino. Use coffeescript, typescript, dart… We also get js linting, image compression and more…

Implementation

At the moment this is just a prototype. It hooks on to plays sbt plugins, start and stop commands and fires up grunt and pipes it’s commands into sbt.

It also makes npm, bower, yo available at the sbt console, so you never have to leave play to get a new dependency or run yo’s scaffolding tasks.

I’ve set it up so that we have a separate root called ui where the (in this case) angular app will live. It uses the public folder as it’s dist output, which means we can then use plays normal Assets controller to include them.

It uses bower to import bootstrap into /ui/components and then we include bootstrap in our main.less file (so that we can use all the awesome mixins)

We also get angular, angular-bootstrap and a couple of shims via bower. By having these in the component.js file we can simply run bower install from the sbt console to get all the components.

When play starts up it also hooks into grunt’s watch command (by running grunt dev, which includes the watch command) This means it will start watching less, and js files (all settings are configurable through the Gruntfile.js)

It also starts up live reload, so by installing the live reload plugin for chrome, you can press cmd + s and see the design getting updated straight away without having to do a refresh.

Conclusion

I think this marriage between backend and frontend is a match made in heaven. It will only get better with the coming web components, where it will no longer be possible to go out and fetch the individual components manually.

https://github.com/leon/play-grunt-angular-prototype

Play Salat 1.2 Released - Image

Play Salat 1.2 Released

Play Framework

I’ve just published play-salat version 1.2

Version 1.2 comes with:

  • Built against Play 2.1.0 to get all the magic the new stuff.
  • Sample updated to Play 2.1.0 and added JSON Rest example
  • Salat 1.9.2-SNAPSHOT to get scala 2.10, I will release version 1.3 as soon as it’s available in release.
  • Mongo Options - Thanks to @ktonga we can now specify loads of settings for our mongo connections. See settings
  • Added JSON Reads and Writes for ObjectId. See example
JSON Action Composition - Image

JSON Action Composition

Play Framework

I wanted to share this action with you since it simplifies dealing with incoming json requests a lot.

This is what we want to accomplish.

instead of having to write this.

def create() = Action(parse.json) { implicit request =>
  request.body.validate[User].fold(
    valid = { user =>
      User.save(user)
      Ok(Json.toJson(user))
    },
    invalid = (e => BadRequest(JsError.toFlatJson(e)).as("application/json"))
  )
}

we want to be able to write this.

import controllers.Actions._

// Make sure there is a implicit Reads[User] available...
def create = JsonAction[User] { user =>
  User.save(user)
  Ok(Json.toJson(user))
}

The implementation

This assumes that you have a JSON Reads[A] available as an implicit variable.

See Writing Reads[T] combinators in the documentation.

Start by putting this in a file called Actions.scala in your controllers dir and as you see in the above example we import all the actions defined in that file by writing import controllers.Actions._

package controllers

import play.api.mvc._
import play.api.libs.json._

object Actions extends Results with BodyParsers {

  /**
   * Simplifies handling incoming JSON by wrapping validation and returning BadRequest if it fails
   * @param action the underlying action
   * @tparam A a class that has an implicit Read available
   * @return a response
   */
  def JsonAction[A](action: A => Result)(implicit reader: Reads[A]): EssentialAction = {
    Action(parse.json) { implicit request =>
      request.body.validate[A].fold(
        valid = { json =>
          action(json)
        },
        invalid = (e => BadRequest(JsError.toFlatJson(e)).as("application/json"))
      )
    }
  }
}

Conclusion

Understanding Scala is a lot harder than Java, at least for me, coming from a non functional background. But after completing the on-line course, functional programming in Scala by Martin Odersky, I feel a lot more comfortable in Scala and Play!