javascriptscalascala.jscross-build

How to Use a Javascript Library in a Scalajs Project


I am following the tutorial here:

https://www.scala-js.org/doc/project/dependencies.html

  1. First things first, I have my project set up like this:

https://github.com/scala-js/scalajs-cross-compile-example

Without making any changes, this runs as expected when I pass in the following commands:

sbt> fooJS/run
sbt> fooJVM/run
  1. Now I want to import this library:

  2. I want to run the following function:

    Plotly.newPlot('myDiv', data);

How can I do this?

My Main.scala file inside the js folder looks like this:

package example

object Main extends App {
  println(s"Using Scala.js version ${System.getProperty("java.vm.version")}")
}

I know a facade for this library already exists, but I would like to be able to create my own facades for future projects, and am using this as an example. I read the tutorial here:

https://www.scala-js.org/doc/interoperability/facade-types.html

But in all honesty I do not follow those steps coming from a different language ecosystem.


Solution

  • “I do not follow those steps” is not a useful way to describe the problems you're having.

    It looks fairly obvious what you need to do. There's a global Object called Plotly, which has a method called newPlot, which takes a String and an array of objects containing the data. So you need something like this:

    @js.native
    @JSGlobal
    object Plotly extends js.Object {
      def newPlot(id: String, data: js.Array[PlotData]) = js.native
    }
    

    Now that we have that, we also need to specify what PlotData is supposed to look like. Unlike the type of the Plotly object, where we merely specify the interface and the actual object is implemented in JS, this type is going to be implemented in Scala, so you need to follow this guide.

    For a scatter type plot, it could look like so:

    case class PlotData(
      x: js.Array[Double],
      y: js.Array[Double]
    ) extends js.Object {
      def type: String = "scatter"
    }