scalaplayframeworkreactivemongoplay-reactivemongo

Scala Play convert a request to JSON and write it to MongoDB


I'm using Play 2.5 and ReactiveMongo. It's a simple problem but I can't figure it out. I have a controller that receives a username and password from a view, I want to convert this request to a model of type UserModel and then convert this model to json and write it to MongoDB.

My controller:

class RegisterController @Inject() (val reactiveMongoApi: ReactiveMongoApi) 
extends Controller with MongoController with ReactiveMongoComponents {

  def registerPost = Action.async { request =>

  implicit val accountWrites = new Writes[UserModel] {
  def writes(account: UserModel) = Json.obj(
    "username" -> account.username,
    "password" -> account.password
  )
} //needs this for some reason?

val future = collection.insert(request.body) //trying to insert to mongo
future.map(_ => Ok)

My model:

case class UserModel(username: String, password: String) {}

object UserModel {

  implicit val format = Json.format[UserModel] //needs this for some reason?

  val userModel = Form(
mapping(
  "username" -> nonEmptyText,
  "password" -> nonEmptyText
)(UserModel.apply)(UserModel.unapply))
}

My view:

@(userForm: Form[UserModel])(implicit messages: Messages)

<h1>Register</h1>

@helper.form(action = routes.RegisterController.registerPost()) {
  @helper.inputText(userForm("username"))
  @helper.inputText(userForm("password"))

  <button type="submit" name="action" value="register">Register</button>

}

Solution

  • These are the key things you need to do:

    => Bind the form request in your controller method , registerPost . For this, you also need to have the form mapping settings. This mapping will help you to generate UserModel object using the form data inside the method. For doing all this, see here ScalaForms

    => You dont need writes here. You can use format to perform both json writes and reads.

    => Now convert the UserModel into JsValue as:

    //usermodel will be generated by binding the form data
    implicit val format = Json.format[UserModel]
    val userModelJson = format.writes(usermodel)
    

    => Then you can simply call the repository as:

    collection.insert(userModelJson)