1

Hi I am using the following for my api in Lift:

case "api" :: "all" :: _ Get req => for {
    val after <- req.param("after")
    val before <- req.param("before")
    val limit <- req.param("limit")
} yield JsonResponse(json(ResponseLimitAfterBefore(limit.toInt,
                                                   after.toString,
                                                   before.toString)))

My issue is if any of the three parameters are missing it gives an error. Can anyone help me with how to assign a value to any of them if any parameter is missing? For example if after is not in the url then how can I assign a default value to after?

Thanks, -Faran

Daniel Werner
  • 1,350
  • 16
  • 26
Faran
  • 71
  • 2
  • 8

1 Answers1

2

If seems you do not understand how for comprehensions work within Scala. Consider the following:

scala> val x: Option[String] = Some("X")
x: Option[String] = Some(X)

scala> val y: Option[String] = None
y: Option[String] = None

scala> for(xx <- x; yy <- y) yield yy
res0: Option[String] = None

scala> for(yy <- y; xx <- x) yield xx
res1: Option[String] = None

Notice that even though xx has a value, the result is None. Given that req.param gives you a Box[String] (which is similar to an Option[String]), you could just do something like this (if you want a response whatever params are passed):

JsonResponse(json(
ResponseLimitAfterBefore(
  limit.map(_.toInt).openOr(0), 
  after.openOr("after default"), 
  before.openOr("another default")
)))

Or, if you just want to provide a default response overall, rather than a paramterised default response:

(for { 
  after <- req.param("after")
  before <- req.param("before") 
  limit <- req.param("limit") 
} yield JsonResponse(json(ResponseLimitAfterBefore(
  limit.toInt, after, before)))
) openOr BadRequestResponse()

I would suggest playing with both LiftResponse subtypes more and also getting a firm grasp on what for comprehensions actually do.

Hope that helps.

Daniel Werner
  • 1,350
  • 16
  • 26
timothy
  • 497
  • 2
  • 8
  • I cant use the latter because i need a default value if one of the params is not in the URL. But the first one wont work im getting an error where it says openOr is not a member of String. for the line after.openOr("defaultvalue"). – Faran Aug 05 '11 at 05:13
  • You want: req.param("after").openOr("default") – timothy Aug 05 '11 at 09:34
  • [INFO] found : String [INFO] required: ?{val flatMap: ?} [INFO] Note that implicit conversions are not applicable because they are ambiguous: [INFO] both method strToS in object JE of type (String)net.liftweb.http.js.JE.Str [INFO] and method stringWrapper in object Predef of type (String)scala.runtime.RichString [INFO] are possible conversion functions from String to ?{val flatMap: ?} [INFO] val after <- req.param("after").openOr("IA175363") [INFO] ^ [ERROR] one error found [INFO] --------------------------------------- – Faran Aug 08 '11 at 01:24
  • I tried that already but I got that error so not sure why it wouldnt work. – Faran Aug 08 '11 at 01:26
  • I got it to work. What I did was: case "api" :: "events" :: "all" :: _ Get req => JsonResponse(json(eventsResponseLimitAfterBefore(req))) Then I defined the function as follows: def eventsResponseLimitAfterBefore(params : HasParams) = { val after = params.param("after") openOr /*value*/ val before = params.param("before") openOr /*value*/ val limit = (params.param("limit") openOr "25").toInt – Faran Aug 08 '11 at 02:22
  • It didn't work previously because you're using the curried form. Sometimes you need to help the Scala inferencer by putting the right parenthesis in place. If you found my original answer helpful, please vote it up. – timothy Aug 09 '11 at 11:12
  • Hey Thanks yeah your answer is what fixed my issue other than my noob Scala skills :) – Faran Aug 09 '11 at 17:38