0
votes

I have a play controller:

def createBlokPost() = Action { implicit request =>
    val postvals: Option[Map[String, Seq[String]]] = request.body.asFormUrlEncoded
    postvals.map { args =>
      val email = args("email").head
      val name = args("name").head
      val population = args("population").head
      val location = args("location").head
      val studentRequirements = args("Student Requirements").head
      val schoolFundingMethod = args("School funding method").head

      val createSchool = modelPersistent.createSchool(email, name, population.toShort, location, studentRequirements.toShort, schoolFundingMethod.toShort)

      var workedVal = false

      createSchool.map { thing =>
        thing match {
          case Some(i) => workedVal = true
          case None => workedVal = false
        }
      }

      if (workedVal) {
        Ok("It frickin worked!")
      } else {
        Ok("Something went wrong on our end :( \nYour school may already have a Blok.")
      }
    }.getOrElse(Ok("Oops. You're a loser. Something went wrong and we cannot help you because in reality... we dont care enough. \nImagine being such a loser that something went wrong on the sign up page ????.\n\nBTW. Every time this happens I get a notification telling me that someone fucked up and do you know what I do? I laugh knowing that there is some degenerate out there with the ability to fail so quickly."))
  }

createSchool is a future[option[Int]]. In my test project this is working so I believe it to be an issue with putting it in the controller. The error I am receiving is:

[error] a.a.ActorSystemImpl - Uncaught error from thread [application-akka.actor.default-dispatcher-10]
scala.runtime.NonLocalReturnControl: null

I do not know what this means but the controller is still completing meaning that the row is added to the database and it returns "Something went wrong on our end :( \nYour school may already have a Blok.". I have also tried a flatMap and onComplete but neither of those are working. Additionally, I tried making the action async but it would not compile.

The issue is that it is not changing the boolean workedVal and it is always returning false even if it is working.

Any help would be greatly appreciated.

1

1 Answers

2
votes

What is happening is basically:

  • the Future result of createSchool(...) is bound to createSchool
  • workedVal is initialized to false
  • a callback is attached to createSchool
  • workedVal is checked and false
  • Ok with the error message is returned
  • The createSchool Future completes
  • The callback is executed, possibly setting workedVal

You'll have to make it an async Action, which means every path has to result in a Future

So something like this should work

postvals.map { args =>
  // the args lookups... they're a bit hinky, but setting that aside
  modelPersistent.createSchool(email, name, population.toShort, location, studentRequirements.toShort, schoolFundingMethod.toShort)
    .map { createResult =>
      if (createResult.isDefined) Ok("It frickin' worked!")
      else Ok("Something went wrong on our end :( \nYour school may already have a Blok.")
    }
}.getOrElse {
  Future.successful(Ok("Oops. You're a loser. Something went wrong and we cannot help you because in reality... we dont care enough. \nImagine being such a loser that something went wrong on the sign up page 😂.\n\nBTW. Every time this happens I get a notification telling me that someone fucked up and do you know what I do? I laugh knowing that there is some degenerate out there with the ability to fail so quickly."))
}