Search code examples
scalascala.jsupickle

upickle: invalid string value during deserialization


I am quite new in scala.js world so I decided to try it out on some small examples and one of them is quite simple get request with parsing of returning json back into scala entity.

Please find code which does it below:

def loadAndDisplayPosts(postsElement: Element) = {
  jQuery.get(
    url = "/posts",
    success = {
      (data: js.Any) =>
        val stringify = JSON.stringify(data)
        console.log(stringify)
        val posts = read[List[Post]](stringify)
        console.log(posts.size)
        posts.map(render).foreach(postsElement.appendChild)
    }
  )
}

console.log(stringify) returns the following json:

[
  {
    "title": "Some fancy title",
    "content": "some very long string with \"escaped\" characters",
    "tags": [
      "algorithms"
    ],
    "created": 1474606780004
  }
]

And when everything comes down to the

read[List[Post]](stringify)

I get the following exception:

upickle.Invalid$Data: String (data: 1474606780004)

So the question is: is anything there that is done wrong? Is there some valid reason for such behavior?

Version of library used:

"com.lihaoyi" %%% "upickle" % "0.4.1"

EDIT:

Adding entity itself:

case class Post(title: String,
                  content: String,
                  tags: List[String] = List.empty,
                  created: Long = System.currentTimeMillis())

EDIT 2:

The following code produces the same error:

val post = Post("Some title", "some \"content\"", List("algorithms"), 1474606780004L)
val json = write[List[Post]](List(post))

Thanks in advance for clarification.


Solution

  • Well, actually the correct answer turned out to be here: upickle read from scalaJS - upickle.Invalid$Data: String (data: 1)

    String is only partially correct answer. You can also use Double (at least you get free conversion from actual long for free on scala side).

    So I ended up with the following entity which works just fine:

    case class Post(title: String,
                      content: String,
                      tags: List[String] = List.empty,
                      created: Double = System.currentTimeMillis())