Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to convert a case class to a js.Object

Tags:

scala.js

Say I have a case class:

case class Name(first: String, last: String)
val n1 = Name("John", "Doe")
val n2 = Name("Mary", "Doe")

and I have a java script object:

@js.native
trait MyJSObject extends js.Object { 
  def add(name: js.Object): Unit = js.native 
}

such that name should be of the format

{"first":"John","last":"Doe"}

What is the best way to convert my case object to a js.Object?

I know this can be achieved doing a upickle.write() to convert it to a json String so I guess my question is is this the best way?

like image 370
user79074 Avatar asked Mar 07 '16 15:03

user79074


1 Answers

If you control the case class, you can just add the @JSExportAll annotation to it:

@JSExportAll
case class Name(first: String, last: String)

This will create properties named first and last. Note that this is not the same as a simple object. However, depending on what the add method does, it is sufficient (and much more lightweight than converting to JSON and parsing again).

In case you need to cross compile the case class, you can include the scalajs-stubs library in your JVM project. It will provide dummy annotations (that are not written to .class files).

If you need a js.Object, you can use the export typechecker:

val x = Name("foo", "bar")
js.use(x).as[js.Object]

This will even work with a trait that defines the fields you need:

@js.native
trait Options extends js.Object {
  def first: String = js.native
  def last: String = js.native
}

val x = Name("foo", "bar")
js.use(x).as[Options]

The js.use(x).as call will fail, if there is a mismatch between the types (i.e. if Options defines a field that Name doesn't define).

like image 74
gzm0 Avatar answered Sep 19 '22 20:09

gzm0