Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play! 2.1.1 framework javascript in template causes compile error

I just started working with the play framework. Loving it except Im having trouble with the view templates.

Whenever I include javascript directly on the view template, I get a compile error. Is this not possible with play! templating?

@(title: String)(content: Html)

<!DOCTYPE html>

<html>
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
        <script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script>
    </head>
    <body>
<script>

function isEmpty(obj) {
    //for(var prop in obj) {
    //if(obj.hasOwnProperty(prop))
    try{
      if(JSON.stringify(obj)=='{}'){
        return true;
      }else{
        return false;
      }
    }catch(e){
      return false;
    }
  }

</script>

I get the error "Not Parsed?" on the line with function isEmpty(obj) {

Thank you in advance.

like image 267
MFD3000 Avatar asked Mar 24 '23 08:03

MFD3000


2 Answers

Even if you are commenting JavaScript line with // for template's parser bracket is a special char:

//for(var prop in obj) {

In general, brackets in Scala templates has special meaning, so building advanced JavaScripts directly in the view causes many problems. You need to still control if new innocent change in JS doesn't brake template parser, or vice versa - if template parser doesn't devastate your scripts. Simplest solution is just separating JS from the view, you have two solutions and I think that first is better:

  1. Save your JS into common *.js file and include it with <script src...> tag. If you need to pass some data from your view, use global JS var first:

    <script>var helloMessage = "Welcome on page @title";</script> 
    <script src="/path/to/your.js"></script>
    
  2. Read the content of JS file (not Scala template!) in your controller and pass as a String to the view, you will need to escape it with Html():

    @(title: String, mySpecialJS: String)(content: Html)
    <!DOCTYPE html>
    <html>
        <head>
            <title>@title</title>
            @Html(mySpecialJS)
        </head>
    <body>
    
  3. You can also join both approaches, for an example if you want to pass o complex object to the JavaScript depending on the controller/view elements, you can also build a JSON object in controller, convert it to String and then include JS with common tag:

    @(title: String, myJsConfig: String)(content: Html)
    <!DOCTYPE html>
    <html>
        <head>
            <title>@title</title>
            <script>var myJsConfig = @Html(myJsConfig)</script> 
            <script src="/path/to/your.js"></script>
        </head>
    <body>
    

So finally in your.js you can use them as usually:

alert(helloMessage);
console.log("Config is...");
console.log(myJsConfig);
like image 64
biesior Avatar answered Apr 06 '23 00:04

biesior


The error is actually not at the isEmpty() line.

If you look at the Play Console the compiler output is pointing to a different place:

! @6e12h60d9 - Internal server error, for (GET) [/] ->

sbt.PlayExceptions$TemplateCompilationException: Compilation error[Not parsed?]
    at sbt.PlayCommands$$anonfun$43.apply(PlayCommands.scala:433) ~[na:na]
    at sbt.PlayCommands$$anonfun$43.apply(PlayCommands.scala:409) ~[na:na]
    at sbt.Scoped$$anonfun$hf5$1.apply(Structure.scala:581) ~[na:na]
    at sbt.Scoped$$anonfun$hf5$1.apply(Structure.scala:581) ~[na:na]
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:49) ~[scala-library.jar:na]
    at sbt.Scoped$Reduced$$anonfun$combine$1$$anonfun$apply$12.apply(Structure.scala:311) ~[na:na]
[warn] play - No application found at invoker init
[error] C:\Users\maba\Development\play\layout\app\views\main.scala.html:14: Compilation error[Not parsed?]
[error]             //for(var prop in obj) {
[error]                               ^
[error] (compile:sources) @6e12hd81d: Compilation error in C:\Users\maba\Development\play\layout\app\views\main.scala.html:14
[error] application -

So there seems to be an error parsing the comments (don't know why at the moment).

So if you want this code to run just use Play comments (@* some comment *@) instead:

<script>

  function isEmpty(obj) {
    @*
    for(var prop in obj) {
    if(obj.hasOwnProperty(prop))
    *@
    try{
      if(JSON.stringify(obj)=='{}'){
        return true;
      }else{
        return false;
      }
    }catch(e){
      return false;
    }
  }

</script>
like image 23
maba Avatar answered Apr 06 '23 01:04

maba