-1

I want to convert variable message which is of type scala.Seq[Scala.Document] to JSON format in following code:

path("getMessages"){
          get {
            parameters('roomname.as[String]) {
              (roomname) =>
                try {
                  val messagesByGroupName = MongoDatabase.collectionForChat.find(equal("groupChatName",roomname)).toFuture()
                  val messages = Await.result(messagesByGroupName,60.seconds)
                  println("Messages:"+messages)
                  complete(messages)
                }
                catch {
                  case e:TimeoutException =>
                    complete("Reading file timeout.")
            }
          }
        }

But it is giving me error on complete(messages) line. It is not accepting message of that type.

I tried to convert it into JSON by using following :

import play.api.libs.json._

object MyJsonProtocol{
  implicit object ChatFormat extends Format[Chat] {
    def writes(c: Chat) : JsValue = {
      val chatSeq = Seq (
        "sender" -> JsString(c.sender),
        "receiver" -> JsString(c.receiver),
        "message" -> JsString(c.message),
        "groupChatName" -> JsString(c.groupChatName),
      )
      JsObject(chatSeq)
    }


    def reads(value: JsValue) = {
      JsSuccess(Chat("","","",""))
    }
  }
}

But it is not working.

My Chat.scala class is as follows:

import play.api.libs.json.{Json, Reads, Writes}

class Chat(var sender:String,var receiver:String,var message:String, var groupChatName:String){
  def setSenderName(senderName:String) = {
    sender = senderName
  }
  def setReceiverName(receiverName:String) = {
    receiver = receiverName
  }
  def setMessage(getMessage:String) = {
    message = getMessage
  }
  def setGroupChatName(chatName:String) = {
    groupChatName = chatName
  }
}

object Chat {
  def apply(sender: String, receiver: String, message: String, groupname: String): Chat
  = new Chat(sender, receiver, message,groupname)

  def unapply(arg: Chat): Option[(String, String, String,String)] = ???
  implicit val requestReads: Reads[Chat] = Json.reads[Chat]
  implicit val requestWrites: Writes[Chat] = Json.writes[Chat]
}

I am also not able to figure out what to write in unapply method. I am new to scala and akka.

EDIT: My MongoDatabase.scala which has collection is as follows:

object MongoDatabase {
  val chatCodecProvider = Macros.createCodecProvider[Chat]()

  val codecRegistry = CodecRegistries.fromRegistries(
    CodecRegistries.fromProviders(chatCodecProvider),
    DEFAULT_CODEC_REGISTRY
  )
  implicit val system = ActorSystem("Scala_jwt-App")
  implicit val executor: ExecutionContext = system.dispatcher
  val mongoClient: MongoClient = MongoClient()
  val databaseName = sys.env("database_name")
  // Getting mongodb database
  val database: MongoDatabase = mongoClient.getDatabase(databaseName).withCodecRegistry(codecRegistry)
  val registrationCollection = sys.env("register_collection_name")
  val chatCollection = sys.env("chat_collection")
  // Getting mongodb collection
  val collectionForUserRegistration: MongoCollection[Document] = database.getCollection(registrationCollection)
  collectionForUserRegistration.drop()
  val collectionForChat: MongoCollection[Document] = database.getCollection(chatCollection)
  collectionForChat.drop()
}

And if try to change val collectionForChat: MongoCollection[Document] = database.getCollection(chatCollection)

to

val collectionForChat: MongoCollection[Chat] = database.getCollection[Chat](chatCollection)

then I get error on in saveChatMessage() method below:

def saveChatMessage(sendMessageRequest: Chat) : String = {
    val senderToReceiverMessage : Document = Document(
      "sender" -> sendMessageRequest.sender,
      "receiver" -> sendMessageRequest.receiver,
      "message" -> sendMessageRequest.message,
      "groupChatName" -> sendMessageRequest.groupChatName)
    val chatAddedFuture = MongoDatabase.collectionForChat.insertOne(senderToReceiverMessage).toFuture()
    Await.result(chatAddedFuture,60.seconds)
    "Message sent"
  }

on val chatAddedFuture = MongoDatabase.collectionForChat.insertOne(senderToReceiverMessage).toFuture() this line since it accepts data of type Seq[Document] and I am trying to add data of type Seq[Chat]

Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
Ruchir Dixit
  • 105
  • 1
  • 9

2 Answers2

0

I am going to assume that MongoDatabase.collectionForChat.find(equal("groupChatName",roomname)) returns either Seq[Chat], or Chat. Both of them are the same for play.

You have 2 options:

  1. Adding the default format on the companion object:

    object Chat {
        implicit val format: Format[Chat] = Json.format[Chat]
    }
    

    In this case you can delete the object MyJsonProtocol which is not used.

  2. In case you want to keep your own serializers(i.e. MyJsonProtocol), you need to rename MyJsonProtocol into Chat. This way the complete route will be able to find the implicit Format.

Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
0
  1. create case class for the message object you want to send for example:
case class MyMessage(sender: String, receiver: String, message: String, groupChatName: String)
  1. You should create Format for the type of case class
implicit val MessageTypeFormat = Json.format[MyMessage]
  1. if complete should get JSON type - then call complete myMessage when myMessage is an instance of MyMessage.
complete(Json.toJson(myMessage))
Zvi Mints
  • 1,072
  • 1
  • 8
  • 20