No Json deserializer found for type List

My scala skill is lacking but I've been wrestling with this. But I'm having a problem serializing and deserializing JSON. I've googled and searched StackOverflow but unfortunately I cannot piece it together.

So this is my last resort..

My model is:

package models

import java.util.UUID
import java.sql.Timestamp


import play.api.db._
import play.api.Play.current
import play.api.libs.json._


import slick.driver.PostgresDriver.simple._
import Database.threadLocalSession

case class User(
  id:UUID,
  username: String,
  password: String,
  email: String,
  comment_score_down: Int,
  comment_score_up: Int,
  post_score_down: Int,
  post_score_up: Int,
  created_on: Timestamp)

object Users extends
  Table[(UUID, String, String, String, Int, Int, Int, Int, Timestamp)]("users"){

  implicit object UserFormat extends Format[User] {

    implicit object UUIDFormatter extends Format[UUID] {
      def reads(s: JsString): UUID = java.util.UUID.fromString(s.toString)
      def writes(uuid: UUID) = JsString(uuid.toString)
    }

    implicit object TimestampFormatter extends Format[Timestamp] {
      def reads(s: JsValue): Timestamp = new Timestamp(s.toString.toLong)
      def writes(timestamp: Timestamp) = JsString(timestamp.toString)
    }


    def reads(json: JsValue): User = User(
        (json \ "id").as[UUID],
        (json \ "username").as[String],
        (json \ "password").as[String],
        (json \ "email").as[String],
        (json \ "comment_score_down").as[Int],
        (json \ "comment_score_up").as[Int],
        (json \ "post_score_down").as[Int],
        (json \ "post_score_up").as[Int],
        (json \ "created_on").as[Timestamp]
      )
     def writes(u: User): JsValue = JsObject(List(
         "id" -> JsString(u.id.toString),
         "username" -> JsString(u.username),
         "password" -> JsString(u.password),
         "email" -> JsString(u.email),
         "comment_score_down" -> JsString(u.comment_score_down.toString),
         "comment_score_up" -> JsString(u.comment_score_up.toString),
         "post_score_down" -> JsString(u.post_score_down.toString),
         "post_score_up" -> JsString(u.post_score_up.toString),
         "created_on" -> JsString(u.created_on.toString)
       ))
  }


  def id = column[UUID]("ID", O.PrimaryKey) // This is the primary key column
  def username = column[String]("username")
  def password = column[String]("password")
  def email = column[String]("email")
  def comment_score_down = column[Int]("comment_score_down")
  def comment_score_up = column[Int]("comment_score_up")
  def post_score_down = column[Int]("post_score_down")
  def post_score_up = column[Int]("post_score_up")
  def created_on = column[Timestamp]("created_on")

  def * = id ~ username ~ password ~ email ~ comment_score_down ~
    comment_score_up ~ post_score_down ~ post_score_up ~ created_on

}

My controller:

  def getUsers = Action {
    val json = database withSession {
      val users = for (u <- Users) yield u.*
      Json.toJson(users.list)
    }
    Ok(json).as(JSON)

  }

Thank you for your time!

Answers


Kay, I got it sweet.

Made some edit to my model:

case class User(
  id:UUID,
  username: String,
  password: String,
  email: String,
  comment_score_down: Option[Int],
  comment_score_up: Option[Int],
  post_score_down: Option[Int],
  post_score_up: Option[Int],
  created_on: Timestamp)

object Users extends Table[User]("users"){     

I also changed my object signature so that it can return type User instead of just User's parameters. And I just have to append <> (User, User.unapply _) to my projection method (the *).

But in my controller:

I just needed:

  implicit object UserWrites extends Writes[User] {

    def writes(u: User) = Json.obj(
         "id" -> JsString(u.id.toString),
         "username" -> JsString(u.username),
         "password" -> JsString(u.password),
         "email" -> JsString(u.email),
         "comment_score_down" -> JsNumber(u.comment_score_down.getOrElse(0).toInt),
         "comment_score_up" -> JsNumber(u.comment_score_up.getOrElse(0).toInt),
         "post_score_down" -> JsNumber(u.post_score_down.getOrElse(0).toInt),
         "post_score_up" -> JsNumber(u.post_score_up.getOrElse(0).toInt),
         "created_on" -> JsString(u.created_on.toString)
    ) 


  }

as member of the controller class.

So now my controller action is just:

  def getUsers = Action {

    val json = database withSession {
      val users = for (u <- Users) yield u
      Json.toJson(users.list)
    }
    Ok(json).as(JSON)
  }

Edit:

Alternatively, I've moved the getUsers code to my model as a findAll method and also moved my writable to there too. I didn't like the data logic being in the controller...

So in my controller I only have a method/action:

  def getUsers = Action {
    Ok(Users.findAll).as(JSON)
  }

My model now looks like:

package models

import java.util.UUID
import java.sql.Timestamp


import play.api.db._
import play.api.Play.current
import play.api.libs.json._


import slick.driver.PostgresDriver.simple._
import Database.threadLocalSession

case class User(
  id:UUID,
  username: String,
  password: String,
  email: String,
  comment_score_down: Option[Int],
  comment_score_up: Option[Int],
  post_score_down: Option[Int],
  post_score_up: Option[Int],
  created_on: Timestamp)

object Users extends Table[User]("users") {

  lazy val database = Database.forDataSource(DB.getDataSource())

  def id = column[UUID]("id", O.PrimaryKey) // This is the primary key column
  def username = column[String]("username")
  def password = column[String]("password")
  def email = column[String]("email")
  def comment_score_down = column[Option[Int]]("comment_score_down")
  def comment_score_up = column[Option[Int]]("comment_score_up")
  def post_score_down = column[Option[Int]]("post_score_down")
  def post_score_up = column[Option[Int]]("post_score_up")
  def created_on = column[Timestamp]("created_on")

  implicit object UserWrites extends Writes[User] {

    def writes(u: User) = Json.obj(
         "id" -> JsString(u.id.toString),
         "username" -> JsString(u.username),
         "password" -> JsString(u.password),
         "email" -> JsString(u.email),
         "comment_score_down" -> JsNumber(u.comment_score_down.getOrElse(0).toInt),
         "comment_score_up" -> JsNumber(u.comment_score_up.getOrElse(0).toInt),
         "post_score_down" -> JsNumber(u.post_score_down.getOrElse(0).toInt),
         "post_score_up" -> JsNumber(u.post_score_up.getOrElse(0).toInt),
         "created_on" -> JsString(u.created_on.toString)
    )
  }

  def * = id ~ username ~ password ~ email ~ comment_score_down ~
    comment_score_up ~ post_score_down ~ post_score_up ~ created_on <>
    (User, User.unapply _)

  def findByPK(pk: UUID) =
    for (entity <- Users if entity.id === pk) yield entity

  def findAll = database withSession {
      val users = for (u <- Users) yield u
      Json.toJson(users.list)
    }

}

Need Your Help

Retrieveing Day, Month and Year separately from Date

sql sql-server-2008 tsql date

Is there an implemented way to retrieve separately day, month and year from a Date field in T-SQL? Everything I've found is to make the process the other way around, in my case I mean if I have

How to add months to date ? Knockout js

javascript knockout.js

I am working on some calculation what i get is no of months, so i need to add to the startdate and display end date dynamically upon added months.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.