3

I have some variables in javascript:

var something = 1;
var url = "@CSRF(routes.Some.thing(something))";

I get an error during compilation because "something" does not refer to the javascript variable, in other words; the compiler can't identify it. Is it possible to convert/inject the javascript variable somehow? Also, does this work in real time in javascript or do I need to prepare an "@CSRF(routes.Some.thing(something))" array containing each possible "something" value?

It's supposed to be a simple rest call, seen in routes file:

/something/:something controllers.Some.thing(something : Long)

An alternative would be to use a form, but I want to try not to.

Marcus Persson
  • 373
  • 4
  • 20
  • Even though the whole thing with play & twirl looks like magic, it still has the "limitation" that the template-stuff is filled out on the server, whereas your javascript variable `something` lives in user's browser, long after the page has been rendered on the server and sent over the network. Since `play` cannot see into the future (and also not into user's browser), this doesn't seem to be possible like this. However, you could pre-compute many different routes, and then add some logic in JS to select the right URL on the client side... – Andrey Tyukin Feb 06 '18 at 16:54
  • @AndreyTyukin Yeah, that's what I thought... Which is why I suggested "prepare an "@CSRF(routes.Some.thing(something))" array containing each possible "something" value". Is this good practice? I have multiple entities that each have a few options. So, it's a lot of routes. – Marcus Persson Feb 06 '18 at 17:21
  • I'm not sure whether this is a good practice... I'd probably try to reframe the whole routing thing as an ordinary ajax-request with parameters, and then make the decision where to redirect on the server-side. Have you looked [here](https://stackoverflow.com/questions/17817174/play-framework-using-javascript-variable-in-scala-template) and [here](https://stackoverflow.com/questions/12501744/putting-javascript-variable-into-play-function)? There are some further links that might be helpful. – Andrey Tyukin Feb 06 '18 at 17:36

1 Answers1

0

You need to use a Javascript Routing and add the CSRF token to the request.

Javascript Rounting description: https://www.playframework.com/documentation/2.6.x/ScalaJavascriptRouting

Look at my answer to the question with explanation how to use it for assets("Correct and long solution"), the usage for other activities is the same: How to update src of a img from javascript in a play framework project?

So in your case, the Javascript routes generation can look like:

JavaScriptReverseRouter("jsRoutes")(
  routes.javascript.Some.thing
)

And in the JavaScript:

var something = 1;
var url = jsRoutes.controllers.Some.thing(something).url;

The last - do not forget to add Csrf-Token header to the request.

Andriy Kuba
  • 8,093
  • 2
  • 29
  • 46
  • I ended up building the csrf-token like this: "@play.filters.csrf.CSRF.getToken.get.value" which I add to the url, or well, header in an ajax call. – Marcus Persson Feb 07 '18 at 12:09