ワーパパエンジニアの学び手帳

ワーパパエンジニアの業務外での学びとかガジェットネタとか

【Playframework/Scala】Okでflashメッセージを表示できない件

Playframework/Scalaflashメッセージを表示したい場合、公式の記述を見るとResultに対して.flashingでkeyとvalueのMapを渡してやればよいとあります。

ScalaSessionFlash - 2.5.x

そこでOkに対して.flashingでメッセージを渡してやっても表示してくれず。。

Controllerはこちら。

class hogeController @Inject() (
  val messagesApi: MessagesApi,
  implicit val webJarAssets: WebJarAssets)
  extends Controller with I18nSupport {

  def index = Action.async { implicit request =>
    ~~
    Future.successful(Ok(views.html.hogeView().flashing("success", "hogehoge"))
  }

Viewはこちら。

@()(implicit request: RequestHeader, messages: Messages, webJarAssets: WebJarAssets)

@request.flash.get("success").map{msg =>
<div class="alert alert-success alert-dismissable">
    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
    <strong>@Html(msg)</strong>
</div>
}
@request.flash.get("error").map{msg =>
<div class="alert alert-danger alert-dismissable">
    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
    <strong>@msg</strong>
</div>
}

Viewを各ページのヘッダに配置して、flashメッセージが設定されている場合には表示するという内容です。
しかし上記のControllerの実装ではメッセージが表示されず。

調べてみると、これで躓いている人は結構いるみたいで。

stackoverflow.com

どうやらResultに対してflashスコープで設定した内容は次のリクエストで利用されるようで、画面表示で使いたいならRedirectしな!という感じっぽい。。
もしくは、上記リンクで記載のようにOkの引数で直接渡してやるか。

直接渡すのはまあいいんですがRedirect時のflashメッセージの実装はできるだけ変えたくない。ってことでViewを以下のようにしました。

@(message: Option[String])(implicit request: RequestHeader, messages: Messages, webJarAssets: WebJarAssets)

@request.flash.get("success").orElse(message).map{msg =>
<div class="alert alert-success alert-dismissable">
    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
    <strong>@Html(msg)</strong>
</div>
}
@request.flash.get("error").map{msg =>
<div class="alert alert-danger alert-dismissable">
    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
    <strong>@msg</strong>
</div>
}

変えたのは引数でOption[String]型のメッセージを受け取るようにしたのと、successメッセージの取得部分(ひとまずはindex表示時のinfoメッセージ的なものの表示を想定しての実装なので、successと一緒に。。)

メッセージ取得部分は、Option#orElseを使っています。
これを使うと、Someの場合にはSomeのまま返却、Noneの場合にはorElseで指定した値を返却するようです。
その後ろのmapをそのまま使うために、Optionで取得するのはそのままにしたかったのですが、ちょうどいい実装方法がありました。
OptionだとgetとかgetOrElseしか使ったこと無かったんですが(浅い独学scala経験。。)、この辺も使いこなせるようになりたいところ。

今回は以上です!

Scalaスケーラブルプログラミング第3版

Scalaスケーラブルプログラミング第3版