I have the following code in my Application
controller:
def index = Action {
var ticketsAvailable = 1
Ok(views.html.index)
}
When I try to run the application, I get this compilation error:
Cannot write an instance of views.html.index.type to HTTP response. Try to define a Writeable[views.html.index.type]
On the line
Ok(views.html.index)
However, when I add parentheses (as shown below), the error disappears:
Ok(views.html.index())
Why is that? I thought that, in Scala, the usage of parentheses is optional when there are no arguments.
It might be instructive to look at the generated Scala code for a simple Twirl template (Twirl is the Play templating engine) called index.scala.html
:
@()
<h1>Hello, world</h1>
By default, Play will compile this to a Scala file in target/scala-2.11/twirl/main/views/html/index.template.scala
, and, if you clean it up a bit to remove source mappings (which enable compile errors in templates to be translated to the right line in the input file) it will look something like this:
package views.html
import play.twirl.api._
object index_Scope0 {
import models._
import controllers._
import play.api.i18n._
import views.html._
import play.api.templates.PlayMagic._
import play.api.mvc._
import play.api.data._
class index
extends BaseScalaTemplate[play.twirl.api.HtmlFormat.Appendable, Format[play.twirl.api.HtmlFormat.Appendable]](play.twirl.api.HtmlFormat)
with play.twirl.api.Template0[play.twirl.api.HtmlFormat.Appendable] {
def apply(): play.twirl.api.HtmlFormat.Appendable = {
_display_ {
{
Seq[Any](format.raw(""""""), format.raw("""<h1>hello, world</h1>"""))
}
}
}
def render(): play.twirl.api.HtmlFormat.Appendable = apply()
def f: (() => play.twirl.api.HtmlFormat.Appendable) = () => apply()
def ref: this.type = this
}
}
object index extends index_Scope0.index
The important thing to note is that views.html.index
is an object, which has the type views.html.index.type
, and that's what you refer to if you don't add parens. This object, however, extends a class called views.html.index_Scope0.index
, which has an apply()
method, which returns an Html
object (or rather, HtmlFormat.Appendable
, which is the unaliased type.)
If you "call" a Scala object, Scala translates (or "de-sugars") that to calling the apply()
method on the object (which is how case class constructors work without using new
.) Hence, if you use parens you get an Html
object which is the result of the rendered Twirl template. If you don't, you just get the compiled template object itself, which Play doesn't know how to write to an HTTP response.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With