Play Framework 2.4 Scala Missing parameter type for implicit request in Action after ActionRefiner

I made an ActionRefiner to read the language of the current request from a parameter in url:

class LangRequest[A](val lang: Lang, request: Request[A]) extends WrappedRequest[A](request) def LangAction(lang: String) = new ActionRefiner[Request, LangRequest] { def refine[A](input: Request[A]) = Future.successful { val availLangs: List[String] = Play.current.configuration.getStringList("play.i18n.langs").get.toList if (!availLangs.contains(lang)) Left { input.acceptLanguages.head match { case Lang(value, _) if availLangs.contains(value) => Redirect(controllers.routes.Application.index(value)) case _ => Redirect(controllers.routes.Application.index(availLangs.head)) } } else Right { new LangRequest(Lang(lang), input) } } } 

and try to use it in action as follows:

  def login(lng: String) = LangAction(lng) { implicit request => Ok("Ok") } 

And here I get this "Missing parameter type" error for an implicit request What am I doing wrong? thanks in advance

+7
source share
1 answer

Note: I am new to Play / Scala. There may be a simpler solution.

You probably had the same scenario as mine. Originally tried to implement code similar to examples in https://www.playframework.com/documentation/2.6.x/ScalaActionsComposition#Putting-it-all-together

The difficulty lies in the implementation of shorter chains of actions than their "connection of all this." For example, I just needed to clarify the action based on the identifier, but I did not need any authentication.

So instead of having userAction andThen ItemAction(itemId) andThen PermissionCheckAction , I just need ItemAction(itemId)

I encountered the same error as you, trying to naively delete the other 2 actions. I believe the problem is that the userAction in the manual indicates / determines which body-parser will use the request.

Removing this part, your request does not know what type of body-parser is, so it does not know [A] the request [A], therefore it complains about the type

My fix: use an action class (not just a function) that the body analyzer can pass to the constructor

 class LeagueRequest[A](val league: League, request: Request[A]) extends WrappedRequest[A](request) class LeagueAction(val parser: BodyParser[AnyContent], leagueId: String)(implicit val ec: ExecutionContext) extends ActionBuilder[LeagueRequest, AnyContent] with ActionRefiner[Request, LeagueRequest]{ def executionContext = ec override def refine[A](input: Request[A]) = Future.successful { inTransaction( (for { leagueIdLong <- IdParser.parseLongId(leagueId, "league") league <- AppDB.leagueTable.lookup(leagueIdLong).toRight(NotFound(f"League id $leagueId does not exist")) out <- Right(new LeagueRequest(league, input)) } yield out) ) } } 

with my controller having

 def get(leagueId: String) = (new LeagueAction(parse.default, leagueId)).async { implicit request => Future(Ok(Json.toJson(request.league))) } 

I was unable to avoid the OP error by using action composition functions, not a class that extends ActionBuilder.

0
source

Source: https://habr.com/ru/post/1244933/


All Articles