I am using play framework 2.5.3 with reactive mongoDB.
import javax.inject._
import model._
import play.api.Logger
import play.api.libs.json._
import play.api.mvc._
import play.modules.reactivemongo._
import reactivemongo.api.ReadPreference
import reactivemongo.play.json._
import reactivemongo.play.json.collection._
import scala.concurrent.{ExecutionContext, Future}
class InsertController @Inject()(val reactiveMongoApi: ReactiveMongoApi)(implicit exec: ExecutionContext) extends Controller with MongoController with ReactiveMongoComponents {
def dataFuture: Future[JSONCollection] = database.map(_.collection[JSONCollection]("data"))
def createFromJson = Action.async(parse.json) { request =>
Json.fromJson[jsonWrapper](request.body) match {
case JsSuccess(data, _) =>
for {
data <- dataFuture
lastError <- data.insert(data)
} yield {
Logger.debug(s"Successfully inserted with LastError: $lastError")
Ok("Inserted into db")
}
case JsError(errors) =>
Future.successful(BadRequest("Something went wrong"))
}
}
Here is my controller and when compiling i get the following exception:
[info] Compiling 6 Scala sources and 1 Java source to /home/***/target/scala-2.11/classes...
[error] /home/***/app/controllers/InsertController.scala:38: No Json serializer as JsObject found for type reactivemongo.play.json.JSONSerializationPack.type. Try to implement an implicit OWrites or OFormat for this type.
[error] lastError <- data.insert(data.pack)
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
[info] Compiling 6 Scala sources and 1 Java source to /home/***/target/scala-2.11/classes...
[error] /home/***/app/controllers/InsertController.scala:38: No Json serializer as JsObject found for type reactivemongo.play.json.JSONSerializationPack.type. Try to implement an implicit OWrites or OFormat for this type.
[error] lastError <- data.insert(data.pack)
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
[error] application -
! @705di1397 - Internal server error, for (GET) [/] ->
play.sbt.PlayExceptions$CompilationException: Compilation error[No Json serializer as JsObject found for type reactivemongo.play.json.JSONSerializationPack.type. Try to implement an implicit OWrites or OFormat for this type.]
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27)
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27)
at scala.Option.map(Option.scala:145)
at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:49)
at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:44)
at scala.Option.map(Option.scala:145)
at play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:44)
at play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:40)
at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17)
at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17)
It recommends writing a Owrites or OFormat for JSONCollection which is part of the reactivemongo.play.json._ package and should already have these defined to my understanding.
Here is my jsonWrapper class:
case class jsonWrapper(tables : tables, userId : String)
object jsonWrapper{
implicit val jsonRead: Reads[jsonWrapper] = (
(JsPath \ "tables").read[tables] and
(JsPath \ "userID").read[String]
)(jsonWrapper.apply _)
implicit val jsonWrites: Writes[jsonWrapper] = (
(JsPath \ "tables").write[tables] and
(JsPath \ "userID").write[String]
)(json => (json.tables, json.userId))
implicit val jsonWrapperFormat : Format[jsonWrapper] = Json.format[jsonWrapper]
}
The tables class also has implictly defined format, Reads and writes.
I orignally used this example to get started: https://github.com/jonasanso/play-reactive-mongo-db#master, which works but when i try to adapt it to my needs (i.e. with my jsonWrapper class) i get this error and do not understand why it is not working.
Many Thanks,
Peter M.
I Found my error.
def createFromJson = Action.async(parse.json) { request =>
Json.fromJson[jsonWrapper](request.body) match {
case JsSuccess(data, _) =>
for {
data <- dataFuture
lastError <- data.insert(data)
} yield {
Logger.debug(s"Successfully inserted with LastError: $lastError")
Ok("Inserted into db")
}
case JsError(errors) =>
Future.successful(BadRequest("Something went wrong"))
}
My case entry initiates an object named "data" which i follow up by overriding with my dataFuture object. Thus, causing the error. I simply had to change the variable names...
I fell kind of silly.