Routes with optional parameter - Play 2.1 Scala

playframework-2.0, playframework-2.1, scala

Solution

Play 2.0 supported `Option` in path parameters, Play 2.1 no longer supports this, they removed the PathBindable for Option.

One possible solution would be:

package extensions
import play.api.mvc._
object Binders {
  implicit def OptionBindable[T : PathBindable] = new PathBindable[Option[T]] {
    def bind(key: String, value: String): Either[String, Option[T]] =
      implicitly[PathBindable[T]].
        bind(key, value).
        fold(
          left => Left(left),
          right => Right(Some(right))
        )

    def unbind(key: String, value: Option[T]): String = value map (_.toString) getOrElse ""
  }
}

And add this to `Build.scala` using `routesImport += "extensions.Binders._"`. Run `play clean ~run` and it should work. Reloading the Binders on the fly only sometimes works.

Problem

So in Play 2.0 I had this: ``` GET /tasks/add controllers.Tasks.addTask(parentId: Option[Long] = None) GET /tasks/:parentId/add controllers.Tasks.addTask(parentId: Option[Long]) ``` With a controller method like this: ``` def addTask(parentId: Option[Long]) = Action { Ok(views.html.addTask(taskForm, parentId)) } ``` And it was working. As I migrated to 2.1, it seems to complain about these lines with: `No URL path binder found for type Option[Long]. Try to implement an implicit PathBindable for this type.` Basically, what I am trying to accomplish is to have route `tasks/add` and route `tasks/123/add` link to the same method that accepts an `Optional[Long]`. Any idea how to do this? Thanks. Ok, so I got a kind of it's not a bug, it's a feature response on Lighthouse: "We removed Option[Long] support in path bindables since it doesn't make sense to have a optional path parameter. You can implement your own path bindable that supports it if you please." So far I have 2 solutions, passing -1 as parentId, which I do not really like. Or having 2 different methods, which probably makes more sense in this case. Implementing the PathBindable doesn't seem too feasible right now, so I will probably stick with having 2 methods.

Original source

Related problems