Search code examples
atmospherescala.jsatmosphere.js

Using atmosphere with Scala js


How can I access the atmosphere API using Scala JS?

So say I have the following in javascript:

var socket = $.atmosphere
...
var request = {
    url: "myurl/path",
    ...
};

request.onOpen = function(response) {
    ...
    subSocket.push("init")
};
...
socket.subscribe(request);

What would its equivalent be in Scala JS?


Solution

  • I came up with the solution below:

    @JSName("$.atmosphere")
    object Atmosphere extends js.Object {
    
        def info(msg: String): Unit = js.native
        def subscribe(request: js.Object): Unit = js.native
    }
    
    trait Response extends js.Object {
        val status: Int = js.native
        val reasonPhrase: String = js.native
        val responseBody: String = js.native
        val headers: Array[String] = js.native
        val state: String = js.native
        val transport: String = js.native
        val error: String = js.native
        val request: String = js.native
        val partialMessage: String = js.native
        val errorHandled: Boolean = js.native
        val id: Int = js.native
    }
    
    class Request(url: String) {
    
        def contentType = "application/json"
        def logLevel = "debug"
        def transport = "transport"
        def fallbackTransport = "long-polling"
    
        def onOpen(res: Response) = {}
        def onReconnect(req: Request, res: Response) = {}
        def onMessage(res: Response) = {}
        def onClose(res: Response) = {}
        def onError(res: Response) = {}
    
        def literal = js.Dynamic.literal(
            url = url,
            contentType = contentType,
            logLevel = logLevel,
            transport= transport,
            fallbackTransport = fallbackTransport,
            onOpen = { (res: Response) => onOpen(res) },
            onReconnect = { (req: Request, res: Response) => onReconnect(req, res) },
            onMessage = { (res: Response) => onMessage(res) },
            onClose = { (res: Response) => onClose(res) },
            onError = { (res: Response) => onError(res) }
        )
    }
    

    Usage is then:

    val request = new Request("myurl/path") {
        override def onOpen(res: Response) = {
            g.console.log("Opened " + res.responseBody)
        }
    }
    Atmosphere.subscribe(request.literal)
    

    This way I can override the various properties/handlers for the request. I am wondering if this can be improved upon however. For example is there an alternative to the usage of JSName?

    @JSName("$.atmosphere")