5

I am trying to write a simple scala.js application. The problem I now have is that I can't figure out why I fail to save data which I get from the server / user.

To be more concrete, here are code snippets:

<!-- in my html -->
<script>
    example.RoomFrontend().setName("@name");
</script>

// in my scala.js src
@JSExport
object RoomFrontend extends js.JSApp {
  var username: Option[String] = None
  @JSExport
  def setName(name: String): Unit = {
    username = Some(name)
    g.console.debug(s"Got user name: $name")
  }

  case object TestUserMessage

  class Render(ctx: dom.CanvasRenderingContext2D) extends Actor {
    override def receive: Receive = {
      case TestUserMessage => g.console.debug(s"user name is $username")
    }
  }

  @JSExport
  def main(): Unit = {
    //... 
    // renderer is akka actorRef 
    dom.window.setInterval(() => render ! TestUserMessage, 50)
  }

So, what happens is the following. I succesfully enter user name, e.g. Blah, I see nice message in the js console saying "Got user name: Blah", but the problem is, each time renderer is called, it says username is None.

I imagine it can be caused by my faulty assigning to a variable in one thread (in js main thread, I don't know is it correct definition), and reading this variable from actor thread... But the same story happends with variables stored in actor itself.

I think I don't understand something basic about how one should use scala.js, for I'm new both to scala and js. Please, can somebody explain this odd behavior?

Andy Silver
  • 155
  • 3
  • 8
  • Just to clarify: this is an Akka.js application? That's a pretty specialized requirement, with a library that's still in-progress last I checked -- you may want to talk to the Akka.js folks about it. That said, my understanding (mind, I've never used Akka.js myself) is that the Actors operate in workers, which have their own separate memory space -- I'm a bit surprised it's even legal to access `username` from the Actor. I don't *think* you can share values like that... – Justin du Coeur Dec 24 '16 at 23:15
  • Yep, thanks for your remark, it's Akka.js application also. – Andy Silver Dec 24 '16 at 23:43
  • I have put all the context into main() method and now everything seems to work... Yet I don't know why :( Another thig I have changed was removing call to setName(...) and passing username to main methd via ugly html injection. – Andy Silver Dec 25 '16 at 00:32
  • Well, the reason it now works but didn't before is that the Actor is essentially a separate process from main(). If I understand it correctly, the Actor shares absolutely *nothing* with the main program, except for messages, so the Actor can't see the `username`. Keep in mind, programming with Actors is pretty specialized stuff, and still pretty rare in Scala.js -- I recommend getting comfortable with the platform first, and then adding Akka.js once you have that basis... – Justin du Coeur Dec 26 '16 at 16:27

0 Answers0