Javascript Routing in play Framework not working - scala

I´m having a curious problem in my application when I use the Javascript Routing of Play Framework. This is the problem:
Screenshot
and this is my code:
class Application extends Controller {
import play.api.mvc._
import play.api.routing._
def javascriptRoutes = Action { implicit request =>
Ok(
JavaScriptReverseRouter("jsRoutes")(routes.javascript.ProcessController.retrieveAllProcess)
).as("text/javascript")
}
}
this is muy route file:
GET /javascriptRoutes controllers.Application.javascriptRoutes
GET /Process/All controllers.ProcessController.retrieveAllProcess
this is the html.scala file:
var option =
{ "url" : #routes.javascript.ProcessController.retrieveAllProcess,
...
}
Thank you so much :).

I think you're confusing the javascript routing with reverse routing.
Javascript routing
Javascript routing is meant to generate javascript code. The generated code defines functions that can be used in your javascript to generate urls at the client side. Since you've defined an Action returning the generated code, you could include it in your page by using
<script type="text/javascript" src="#routes.Application.retrieveAllProcess()"></script>
Note that this uses reverse routing to tell the html page which URL should be used for the script. :)
Then in your javascript code it can be used like so
var retrieveAllProcessRoute = jsRoutes.controllers.Application.retrieveAllProcess()
to generate a javascript object containing both the HTTP verb and url to the Application::retrieveAllProcess method.
Reverse routing
Reverse routing is used to generate scala code. This code is meant to generate URLs in views or Redirects to controller methods on the server side.
Since you're talking about a template (*.html.scala), you're talking about the server side of things. This means that you should use the reverse routing capabilities of Play. Below I've rewritten your javascript template snippet to use reverse routing:
var option = {
"url": #routes.Application.retrieveAllProcess,
...
}

Related

Dustjs helper for frontend

So I am using Dustjs on Sailsjs for my project.
I am rendering the first page on the server, and then use the same template client-side.
Problem: My template contains a global sails service which doubles as a dustjs helper:
{#sails.services.globalutils.hyphenator str=title/}
But, on the client-side, I am unable to uyse this service. How can I export this service to the client without going for a JS solution? Can it be bundled with the dustjs template ?
A {#section} signals that Dust should look in the context provided to dust.render(). So as long as the hyphenator function doesn't have server-side dependencies, you can just bring it along in your client-side context. Sails services are just Javascript modules in the api/services folder, so try requireing the relevant module, grabbing its hyphenator property, and passing that along to the client to use in the client's render call.
{
"sails": {
"services": {
"globalutils": {
"hyphenator": function(chunk, context, bodies, params) {
// do some hyphenation
}
}
}
}
}
Of course, if hyphenator has logic that relies on the server, you can't just move it to the client. You could expose a server-side API that your script calls, and couple that with chunk.map to create an asynchronous Dust block.

How to call a Scala function from Play html template

I am new to Scala/Play Framework.
Currently, I am trying to call a Scala function from my html page: test.scala.html and pass the hash parameters to the Scala function.
I added the following lines to routes:
GET /hello controllers.Application.test
POST /hello controllers.Application.hello
In my test.scala.html I have:
#params = { window.location.hash }
#helper.form(action = routes.Application.hello) {
}
And my hello function is defined as:
def hello() = Action {
Ok("Hello !")
}
I am completely confused by the concept of routing and # so I am not too sure which part I did right and which part I did wrong. Please point out my mistakes.
Thanks in advance.
If the function is returning an action, not content to be displayed formatted inside view (HTML), you may want to route request to this action, from a link click or a form submit, to url configured in routing (aka /hello).
To add a parameter you need to either add it as url query string (e.g. for a link → /hello?p=1), or with an input/field for a form (e.g. <input type="text" name="p" value="1" />).
You can use reverse routing to get URL to call configured action. For example for a form POST to hello: <form action="#routes.MyController.hello()" method="POST">.... In this case you will need to look at form mapping, to extract parameters from request.
1) Concept of routing
The main purpose of this routing is simply to translate each incoming HTTP request to an Action in any of your Controller. By Reverse Routing its simply let you use the right part, controllers.Application.hello, in your HTML/Controller/else.
So, for your 2 URLs above, it's likely to say that if there is a request /hello with method GET then it will go to Application controller and test method. If you don't understand the role of each Routing method, please read this documentation..
2) the magic # character
# is a character that you can use in your HTML file if you need to use the Scala code or variables. It's like you can combine PHP code in your HTML file, if you're a PHP developer.
Here is the full-documentation of what you can do with this # character.
3) pass the hash to the controller
To this specific case the simplest way would be passing the value trough a form:
#helper.form(action = routes.Application.hello) {
#helper.inputText(myForm("username"), 'id -> "username", 'size -> 30, 'value -> 'value here' )
}
However, if you're a new Play developer, then I'm afraid you need to read about Form Submission and Form Helper in Play Framework..

Reverse routing on an application deployed in a Tomcat context

I am developing a Play 1.2.5 application that will be installed in a Tomcat context:
http://mytomcat:8080/myapp
And in my routes file I have:
GET /companies/{companyID}/employees Employees.getForCompany
As per the instructions for deploying a Play application in a Tomcat context, I am generating URLs exlusively using the Reverse Router. This works fine, but I am not sure what to do in the case of a jQuery method such as an Ajax request of this style:
var companyID = $('#companies').find(":selected").val();
$.ajax({
url : "#{Employees.getForCompany(companyID)}",
...
});
Obviously the value of companyID isn't known at the time of the generation of the HTML and the resolution of routes by the reverse router.
The only solution that I can see is to reconfigure my routes file so that the URLs are different and the parameters are always at the end, but that makes the REST URLs less logical.
GET /companies/employees/{companyID} Employees.getForCompany
Is there a better way?
I have found the solution myself - Play includes the jsAction tag which generates a function that builds the correct URL:
var companyURL = #{jsAction #Employees.getForCompany(':companyID') /}
$.ajax({
url : companyURL({companyID:companyID}),
...
});
Like that I can maintain the preferred routes mapping:
GET /companies/{companyID}/employees Employees.getForCompany

Play Framework 2.1: Scala: how to get the whole base url (including protocol)?

Currently I am able to get the host from the request, which includes domain and optional port. Unfortunately, it does not include the protocol (http vs https), so I cannot create absolute urls to the site itself.
object Application extends Controller {
def index = Action { request =>
Ok(request.host + "/some/path") // Returns "localhost:9000/some/path"
}
}
Is there any way to get the protocol from the request object?
Actually there's a simple way to do it using Call class that reverse routers use to achieve similar thing.
Given that you are within the scope of implicit request, you can do something like this:
new Call(request.method, input.request).absoluteURL()
and it will provide you with the complete url (protocol, host, route and parameters).
In Play 2.3 and later you can use the secure property of the Request class.
I don't think there is.
Play Framework 2.0 itself does not support https, see: play-framework [2.0] HTTPS
The implementation of absoluteURL method of the Call class of the Play Framework 2.0 does not suggest it.
A workaround is to use a protocol relative urls using //domain.com/path.
This however does not help you with links in email. In that case you could put the protocol in the application.conf. In most cases the difference is made because production supports https and development does not.
I have yet to find a situation where the above workarounds do not work.
Actually your portnumber will give you if it's http or https.
Start your Play server with https support JAVA_OPTS=-Dhttps.port=9001 play start
Here's a code snippet (you can make the validation more stable with a regex, take the https port number from properties ...)
def path = Action { request =>
val path =
if(request.host.contains(":9000"))
"http://" + request.host + "/some/path"
else
"https://" + request.host + "/some/path"
Ok(path)
}
The code will return
http://ServerIp:9000/some/path if it's thru http
https://ServerIp:9001/some/path if it's thru https
My solution was to pass the beginning of the url as an additional parameter from javascript.
The application.conf solution does not work for me, because the same application is accessible on http and https but from different subnet and domain.

Play Framework - Redirect with params

I am trying to figure out how to do a redirect within a controller action in Play (2.0) using Scala.
The redirect using
Redirect(routes.Application.index)
works just fine.
What I cannot figure out from the docs, API, or Google is how to add parameters to the call.
I am coming from Grails where this could be done easily as follows:
redirect action: "index", params: ["key": "value"]
.
The only way I have found is to call Redirect using a string url and a query string, which seems awkward.
Basically I would like to make use of Redirect(Call) somehow, but I do not how to create the Call object using reverse routing.
Am I missing something/not getting the concept in Play/Scala?
Thanks in Advance!
Ellou'
A route is just a function, so you can pass arguments as usual:
// Redirect to /hello/Bob
def helloBob = Action {
Redirect(routes.Application.hello("Bob"))
}
This snippet comes from http://www.playframework.org/documentation/2.0/ScalaRouting (at the bottom)
You can also avoid creating another function just for this in your controller. In your route config, you can simply add something like this:
GET /google #controllers.Default.redirect(to = "http://google.com")