spray / spray-json

A lightweight, clean and simple JSON implementation in Scala
Apache License 2.0
972 stars 190 forks source link

Cannot find JsonWriter or JsonFormat type class for scala.collection.immutable.Map[String,Object] #212

Closed lexicalunit closed 7 years ago

lexicalunit commented 7 years ago

I'm just trying to convert a simple Map into JSON (type String):

  object DeviceActivatorConverters {
    import scala.language.implicitConversions

    implicit def toPayload(item: DeviceActivationRequest): String = {
      import spray.json._
      import spray.httpx.SprayJsonSupport._
      import spray.json.DefaultJsonProtocol._
      import DefaultJsonProtocol._

      val e = Map(
        "user" -> Map(
          "domain" -> item.domain,
          "id" -> item.userId
        ),
        "manufacturer" -> item.manufacturer,
        "model" -> item.model,
        "serial_number" -> item.serialNumber,
        "attributes" -> Map(
          "advertised_name" -> item.advertisedName,
          "bluetooth_device_address" -> item.bluetoothDeviceAddress,
          "mac_address" -> item.macAddress,
          "firmware_version" -> item.firmwareVersion,
          "hardware_version" -> item.hardwareVersion
        )
      )

      val j = e.toJson

      j.toString
    }
  }

I am getting an error on the e.toJson line:

Error:(163, 17) Cannot find JsonWriter or JsonFormat type class for scala.collection.immutable.Map[String,Object]
      val j = e.toJson
Error:(163, 17) not enough arguments for method toJson: (implicit writer: spray.json.JsonWriter[scala.collection.immutable.Map[String,Object]])spray.json.JsValue.
Unspecified value parameter writer.
      val j = e.toJson
klpx commented 7 years ago

As compiler says you dont have JsonWriter for scala.collection.immutable.Map[String,Object]. Likely you dont have JsonWriter for Object (Error:(163, 17) not enough arguments). You need to build map with Serializable type: Map[K: JsonWriter, V: JsonWriter]; Map[String, String] for exmple, but not Map[String, Object]. One of variant is do this (e is Map[String, JsValue]):

 val e = Map(
        "user" -> Map(
          "domain" -> item.domain.toJson,
          "id" -> item.userId.toJson
        ).toJson,
        "manufacturer" -> item.manufacturer.toJson,
        "model" -> item.model.toJson,
        "serial_number" -> item.serialNumber.toJson,
        "attributes" -> Map(
          "advertised_name" -> item.advertisedName.toJson,
          "bluetooth_device_address" -> item.bluetoothDeviceAddress.toJson,
          "mac_address" -> item.macAddress.toJson,
          "firmware_version" -> item.firmwareVersion.toJson,
          "hardware_version" -> item.hardwareVersion.toJson
        ).toJson
      )
lexicalunit commented 7 years ago

Thanks @klpx! Closing ticket.