Play 2.4: Form: could not find implicit value for parameter messages: play.api.i18n.Messages

Solution 1:

After adding implicit messages parameters to views you can just add the following imports and use the old controller classes or even objects without any additional changes:

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

Solution 2:

Using view form helpers (such as @inputText) requires you to pass an implicit play.api.i18n.Messages parameter to your view. You can do this adding (implicit messages: Messages) to the signature in your view. Your view becomes this:

@(helloForm: Form[(String,Int,Option[String])])(implicit messages: Messages)

@import helper._

@main(title = "The 'helloworld' application") { 
  <h1>Configure your 'Hello world':</h1> 
  ...

Then in your application controller you must make this parameter implicitly available in your scope. The simplest way to do this is to implement play's I18nSupport trait.

In your example, this would look like this:

package controllers

import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import javax.inject.Inject
import play.api.i18n.I18nSupport
import play.api.i18n.MessagesApi

import views._

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

  val helloForm = Form(
    tuple(
      "name" -> nonEmptyText,
      "repeat" -> number(min = 1, max = 100),
      "color" -> optional(text)
    )
  )

  def index = Action {
    Ok(html.index(helloForm))
  }

  def sayHello = Action { implicit request =>
    helloForm.bindFromRequest.fold(
      formWithErrors => BadRequest(html.index(formWithErrors)),
      {case (name, repeat, color) => Ok(html.hello(name, repeat.toInt, color))}
    )
  }
}

In your controller you can of course use your own implementation of MessagesApi. Since play knows out of the box how to inject a MessagesApi you can simply annotate your controller with @Inject and let play do the work for you.

As Matthias Braun mentioned, you also have to set

routesGenerator := InjectedRoutesGenerator

in your build.sbt

See https://www.playframework.com/documentation/2.4.x/ScalaI18N for more information about I18n.

Solution 3:

Using form helpers requires you to pass an implicit play.api.i18n.Messages parameter to your view. You can do this adding (implicit messages: Messages) to in your view. Your view becomes this:

@(contacts: List[models.Contact], 
  form: Form[models.Contact])(implicit messages: Messages)

Then manually inject into your controllers

import play.api.data.Forms._

import javax.inject.Inject

import play.api.i18n.I18nSupport

import play.api.i18n.MessagesApi 

then finally add on to your main index controller class

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