Javascript Interoperability
Javascript Routers
Out of the box, PSPS comes with two Play Javascript routers, listed below.
feRoutes
-
Holds routes for front-end related api. Present in all pages, as it is included in
. beRoutes
-
Holds routes for back-end related api. Included in
. This router is only available to logged-in users.
These routers are defined in HomeCtrl
. In order to force browsers to reload the routers only when they change, we has the route sequence, and pass the hash value as a parameter. This is done in the following way:
object HomeCtrl {
...
val beRouteSeq = Seq( (1)
routes.javascript.UserCtrl.apiAddUser,
routes.javascript.UserCtrl.apiReInviteUser,
routes.javascript.UserCtrl.apiDeleteInvitation
)
val beRouteHash:Int = Math.abs(beRouteSeq.map( r => r.f + r.name ).map( _.hashCode ).sum) (2)
class HomeCtrl @Inject()(deadbolt:DeadboltActions, cc: ControllerComponents,
langs: Langs, messagesApi: MessagesApi
) extends AbstractController(cc) with I18nSupport {
...
def backEndRoutes = deadbolt.SubjectPresent()() { implicit request => (3)
Future(Ok(
routing.JavaScriptReverseRouter("beRoutes")(
HomeCtrl.beRouteSeq: _*
)).as("text/javascript"))
}
...
}
}
1 | A sequence of the actions in the routes |
2 | A hash of the above sequence |
3 | Returning the actual router (using Scala’s : _* operator) |
And then, in the template:
<script src="@routes.HomeCtrl.backEndRoutes()?@controllers.HomeCtrl.beRouteHash"></script>
PlayJax
JS Library to make JS6 fetch
calls using Play’s JS Routers. Supports
CSRF, by adding an HTML element with id Playjax_csrfTokenValue
and
value of the current CSRF token.
function resendEmail(uuid){
new Playjax(beRoutes).using(c=>c.UserCtrl.apiReInviteUser(uuid)).fetch()
.then( resp => {
if (resp.ok) {
Informationals.makeSuccess("Invitation re-sent", "", 1500).show();
} else {
Informationals.makeDanger("Re-sending the invitation failed", "", 1500).show();
}
});
}