2

First I have implemented a method to build a Map[Double, String] from a csv file. The map contains (k,v) of saleId, saleType. Here is how I've implemented this:

val stream : InputStream = getClass.getResourceAsStream("/sales.csv")
  val lines: Iterator[String] = scala.io.Source.fromInputStream(stream).getLines
  val map: Map[Double, String] = lines
    .map(_.split(","))
    .map(line => (line(0).toDouble, line(1).toString))
    .toMap

Now I want to go further and get data for building a map with data from API. With the same k,v (saleId, saleType). Json returned by API contains this data as fields.

Json look like this:

   [{ 
    "saleId": 1234, 
    "name": "New name", 
    "saleType": "New Type"
    }, 
    { 
    "saleId": 2345, 
    "name": "New name1", 
    "saleType": "New Type1" 
   }]

So I tried the approach using ScalaJson Play Framework. Since I only need two fields from JSON I decided to use a case class SalesData.

object SalesProcessor {
    case class SalesData(saleId: Int, saleType: String)
    implicit val of: Reads[SalesData] = reads[SalesData]

      val rawJson: String = Source.fromURL("https://mytest.com/api/sales.json").mkString
      val salesJson: JsValue = Json.parse(rawJson)
      val salesData: SalesData = salesJson.as[SalesData]

    def main(args: Array[String]): Unit = {
        println(salesData.saleId)
    }

When I run the above code I'm getting the following error:

play.api.libs.json.JsResultException: JsResultException(errors:List((,List(JsonValidationError(List(error.expected.jsobject),WrappedArray())))))

UPD: After I've used a solution proposed by tea-addict it started failing with the following error:

JsResultException(errors:List((/saleId,List(JsonValidationError(List(error.path.missing),WrappedArray()))), (/saleType,List(JsonValidationError(List(error.path.missing),WrappedArray())))))
2
  • Can you show a sample of the sales.json file Commented Jul 18, 2018 at 14:30
  • @Seraf added Json example to the post Commented Jul 18, 2018 at 15:56

1 Answer 1

1

You can read specific fields and create your SalesData like this.

Sales.json

[{ 
  "saleId": 1234, 
  "name": "New name", 
  "saleType": "New Type"
}, 
{ 
  "saleId": 2345, 
  "name": "New name1", 
  "saleType": "New Type1" 
 }]

Code

object SalesProcessor {
    case class SalesData(saleId: Int, saleType: String)
    implicit val saleReads: Reads[SalesData] = (
        (JsPath \ "saleId").read[Int] and
        (JsPath \ "saleType").read[String]
    ) (SalesData.apply _)

    val rawJson: String = Source.fromURL("https://mytest.com/api/sales.json").mkString
    val salesJson: JsValue = Json.parse(rawJson)
    val salesData: List[SalesData] = salesJson.as[List[SalesData]]

    def main(args: Array[String]): Unit = {
        println(salesData(0).saleId)
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

I need only two fields from json file: saleId and saleType. Sorry for misrepresenting the json file, it actually has the same field names as the case class
Still getting JsResultException(errors:List((/saleId,List(JsonValidationError(List(error.path.missing),WrappedArray()))), (/saleType,List(JsonValidationError(List(error.path.missing),WrappedArray()))))) . Could it be caused by the json structure (objects wrapped into array)? I've updated my post with the valid example of json
val salesData: List[SalesData] = salesJson.as[List[SalesData]]
I've changed to List[SalesData] as you suggested above. And called salesData.foreach(sale => println(sale.saleId + " " + sale.saleType)). Now getting JsonValidationErrors: ((1234)/saleId,List(JsonValidationError(List(error.expected.jsnumber),WrappedArray()))), ((2345)/saleId,List(JsonValidationError(List(error.expected.jsnumber),WrappedArray()))) ..... etc
Thank you soo much! You really helped me to reevaluate my solution and to look at the problem from different sides.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.