Divyanshu
Divyanshu

Reputation: 290

scala-js "@JSGlobalScope" error when migrating to scala-js 1.1.1

I had a fallowing snippet of code in scala-js(0.6.33)

object Main2 extends App {

  val js = for {
    jsTest <- JSTest.js1.toOption
  } yield jsTest

  println(JSTest.js1)
}

import scala.scalajs.js
import scala.scalajs.js.annotation.JSGlobalScope

@js.native
@JSGlobalScope
object JSTest extends js.Object {
  def js1: js.UndefOr[JS2] = js.native
}
@js.native
trait JS1 extends js.Object {

  def js1: js.UndefOr[JS2] = js.native
}
@js.native
trait JS2 extends js.Object {
  def js2: js.UndefOr[Int] = js.native
}

And I was migrating the project to use scala-js(1.1.1)

when I compile the same code in scala-js(1.1.1), I am getting this error: -

const value = js1;
              ^

ReferenceError: js1 is not defined

Can anyone help me achieve the same functionality with scala-js(1.1.1)?

configuration: -

scala -> 2.13.3, sbt -> 1.3.13, jvm -> 14

Upvotes: 1

Views: 85

Answers (1)

sjrd
sjrd

Reputation: 22085

As the release notes of Scala.js 1.0.0 explain, trying to even read a member of an @JSGlobalScope object that does not actually exist in the global scope will throw a ReferenceError, whereas Scala.js 0.6.x would give undefined.

The same section of the release notes explains that, if the purpose is to check whether it is defined, it is now necessary to use an explicit test with js.typeOf. In your specific example:

object Main2 extends App {
  val js = for {
    jsTest <- JSTest.js1.toOption
  } yield jsTest

  println(JSTest.js1)
}

That would mean that you can't unconditionally access JSTest.js1 like that anymore. You first have to make sure it exists using a js.typeOf test:

object Main2 extends App {
  val safeJS1 =
    if (js.typeOf(JSTest.js1) == "undefined") None
    else JSTest.js1.toOption

  val js = for {
    jsTest <- safeJS1
  } yield jsTest

  println(safeJS1)
}

Upvotes: 2

Related Questions