I have a method, with have a lot of implicit parameters:
def hello(message:String)(implicit a:A,b:B,c:C, ..., user: User) = {...}
Now consider such a class:
object Users extends Controller {
implicit a: A = ...
implicit b: B = ...
...
def index(id:String) = Action {
User.findById(id) match {
case Some(user) => {
implicit val _user = user
hello("implicit")
}
case _ => BadRequest
}
}
}
You can see this line in the above sample:
implicit val _user = user
It exists just to make the object user
as an implicit object. Otherwise, I have to call hello
as:
hello("implicit")(a,b,c,... user)
I'm thinking if there is any way to improve the code, e.g. we don't need to define that _user
variable but make the user
is implicit.
Yes, there is a way to eliminate _user
variable while making user
implicit:
def index(id:String) = Action {
User.findById(id) map (implicit user => hello("implicit")) getOrElse BadRequest
}
UPDATE: Addressing your question about many cases in the comments below.
It all depends what value type is returned by User.findById
. If it's Option[User]
but you want to match on specific users (assuming User
is a case class), then the original solution still applies:
def index(id:String) = Action {
User.findById(id) map { implicit user =>
user match {
case User("bob") => hello("Bob")
case User("alice") => hello("Alice")
case User("john") => hello("John")
case _ => hello("Other user")
}
} getOrElse BadRequest
Or you can match on anything else if you want, as long as User.findById
is String => Option[User]
If, on the other hand, User.findById
is String => User
then you can simply define a helper object like:
object withUser {
def apply[A](user: User)(block: User => A) = block(user)
}
And use it as follows (again assuming User
is a case class):
def index(id: String) = Action {
withUser(User findById id) { implicit user =>
user match {
case User("bob") => hello("Bob")
case User("alice") => hello("Alice")
case User("john") => hello("John")
case _ => BadRequest
}
}
}
or matching on some other value, say an Int
:
def index(id: String, level: Int) = Action {
withUser(User findById id) { implicit user =>
level match {
case 1 => hello("Number One")
case 2 => hello("Number Two")
case 3 => hello("Number Three")
case _ => BadRequest
}
}
}
I hope this covers all the scenarios you may have.
I know of no trick such as case Some(implicit user)
but what about
def hello(message: String, user: User)(implicit a: A, ... z: Z) = ...
def hello(message: String)(implicit a: A, ... z: Z, user: User) = hello(message, user)
case Some(user) => hello("implicit", user)
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