2
votes

Compilation error: missing arguments for method apply in class newPost; follow this method with `_' if you want to treat it as a partially applied function

I don't understand how template handling methods have to look like and what complier require of me.
https://github.com/flatlizard/blog

controller:

  def addPost = Action{ implicit request =>
    Ok(views.html.newPost(postForm))
  }

  def createPost = Action { implicit request =>
    postForm.bindFromRequest.fold(
      hasErrors => BadRequest,
      success => {
        Post.create(Post(new Date, success.title, success.content))
        Ok(views.html.archive("my blog", Post.all))
      })
  }

routes:

GET        /archive/new         controllers.Application.addPost
POST       /archive             controllers.Application.createPost

view:

@(postForm: Form[Post])(content: Html)(implicit messages: Messages)
@import helper._

@form(routes.Application.createPost) {
    @inputDate(postForm("date"))
    @textarea(postForm("title"))
    @textarea(postForm("content"))
    <button id="submit" type="submit" value="Submit" class="btn btn-primary">Submit</button>
}

UPDATE

I solved problem adding the following imports in controller file:

import play.api.i18n.Messages.Implicits._
import play.api.Play.current

See Play 2.4 migration: https://www.playframework.com/documentation/2.4.x/Migration24#I18n

2

2 Answers

3
votes

Compilation error

Your view expects three parameters to be passed, but you are passing only one. To solve your compilation error, change the signature in your view from@(postForm: Form[Post])(content: Html)(implicit messages: Messages) to @(postForm: Form[Post])(implicit messages: Messages).

Parameters and views

The second parameter in your example (content: Html) is used when you combine several views:

index.scala.html

@(text: String)

@main("Fancy title") {
  <div>@text</div>
}

main.scala.html

@(title: String)(content: Html)

<html>
  <head>
    <title>@title</title>
  </head>
  <body>
    @content
  <body>
</html>

Call in controller

Ok(views.html.index("Some text"))

In this example you are passing "Some text" to index view. Index view then calls main view passing another two parameters. title and content, where content is the html in between the curly braces of index.scala.html (<div>@text</div>)

Finally implicit parameters: (implicit messages: Messages) must be somewhere in scope to be passed implicitly to your view. For example like this in your controller:

def addPost = Action{ implicit request =>
   implicit val messages: Messages = ...
   Ok(views.html.newPost(postForm))
}
1
votes

I solved problem adding the following imports in controller file:

import play.api.i18n.Messages.Implicits._
import play.api.Play.current

See Play 2.4 migration: https://www.playframework.com/documentation/2.4.x/Migration24#I18n

Update

Actually this is a bad way cause here used Play.current which will become deprecated soon. Here another solution using dependency injection:

routes:

GET        /archive/new         @controllers.Application.addPost
POST       /archive             @controllers.Application.createPost

controller:

class Application @Inject() (val messagesApi: MessagesApi)
  extends Controller with I18nSupport{
 ...
}

https://www.playframework.com/documentation/2.4.x/ScalaDependencyInjection