Search code examples
javascalaplayframeworkplayframework-2.2playframework-2.3

how to get the response of called Action within an Action in play framework


i have two Actions in different controllers ActionA and ActionB i am calling ActionB in ActionA and i want to get its(ActionB) response in ActionA is it possible ? how can i achive this please help here is my code

class ControllerA extends Controller{

def ActionA = Action { implicit request =>
    var jsonRequest = request.body.asJson.get
    val uuid = (jsonRequest \ "uuid").as[String]
    log.info("in ActionA" + uuid)
    val controllerB= new ControllerB
    val actionB=controllerB.ActionB.apply(request)
    //here i want to get the response of ActionB and return this response as the response of ActionA whether its OK or InternelServerError
    Ok("i want to show the response of ActionB")
    }
}

class ControllerB extends Controller{
def ActionB = Action { implicit request =>
    var jsonRequest = request.body.asJson.get
    val uuid = (jsonRequest \ "uuid").as[String]
    log.info("in ActionB " + uuid)
    try {
      Ok("i am ActionB with id {}"+uuid)
    } catch {
      case e: Exception =>
        log.error("Exception ", e)
        val status = Http.Status.INTERNAL_SERVER_ERROR
        InternalServerError(Json.obj("status" -> status, "msg" -> ServerResponseMessages.INTERNAL_SERVER_ERROR))
    }
  }
}

please help


Solution

  • In play 2.2 and 2.3 controllers are typically an object instead of a class so I changed your controllers to be objects. In newer versions of play controllers are classes that are injected using the Guice framework.

    Since invocations of actions is asynchronous, you need to change ActionA to be Action.async. Below are the changes that I made:

    object ControllerA extends Controller{
    
      def ActionA = Action.async { implicit request =>
        var jsonRequest = request.body.asJson.get
        val uuid = (jsonRequest \ "uuid").as[String]
        log.info("in ActionA" + uuid)
        ControllerB.ActionB(request)
      }
    }
    
    object ControllerB extends Controller{
      def ActionB = Action { implicit request =>
        var jsonRequest = request.body.asJson.get
        val uuid = (jsonRequest \ "uuid").as[String]
        log.info("in ActionB " + uuid)
        try {
          Ok("i am ActionB with id {}"+uuid)
        } catch {
          case e: Exception =>
            log.error("Exception ", e)
            val status = Http.Status.INTERNAL_SERVER_ERROR
            InternalServerError(Json.obj("status" -> status, "msg" -> ServerResponseMessages.INTERNAL_SERVER_ERROR))
        }
      }
    }
    

    As the previous answer alluded to, it's far more advantageous to have shared controller code in a service layer that sits below your controllers as opposed to sharing controller code directly. Given your simplistic example though it seems OK to do what you're doing.