I'm testing Koa.js in my Project Kotlin/JS but i c...
# javascript
f
I'm testing Koa.js in my Project Kotlin/JS but i cant make equivalent in kotlin for
async
and
await
from middleware of koa. Koa router:
Copy code
const router = require('koa-router')()

router.get('/', async (ctx, next) => {
  await ctx.render('index', {
    title: 'Hello Koa 2!'
  })
})
I tried with js() function and coroutines but cant make it work. Any hint or confirm if avaible in kotlin/JS?
a
coroutines are the right way here, kotlinx-coroutines-js maps suspension to/from promises (which is what js async/await is)
1
so
promise { … }
is effectively an async function, and you can call
.await()
on a promise expression
(although technically in this case it looks like you can just pass the promise back through?)
but sth like:
Copy code
router.get("/", { ctx, next -> promise {
  ctx.render("index", jsObject {
    title = "Hello Koa 2!"
  }).await()
} })
f
@araqnid How you call
promise{}
block inside of router? I try with
coroutineScope
but throws msg error
Suspension functions can be called only within coroutine body
Copy code
external fun require(module: String): dynamic

suspend fun foo() {
    val ejsArgs: dynamic = object {}
    ejsArgs["title"] = "Hello Koa 2!"

    val router = require("koa-router")()
    router.get("/") { ctx, next ->
        coroutineScope {
            promise {
                ctx.render("index", ejsArgs).await()
            }
        }
    }

    return router
}
a
tbh I’d try getting it working with GlobalScope.promise initially, it’s not clear to me what the scope should be here. Probably you will need some sort of “application” scope to use.
f
@araqnid, I change my code follow your instructions and work
Copy code
router.get("/index2") { ctx, next ->
        GlobalScope.promise {
            //js("await") Error in when call in browser
            ctx.render("index", ejsArgs)
        }
 }
But dont have
await
.
👍 1
e
You’d still need to do
ctx.render("…").await()
. The body of
GlobalScope.promise{ }
is a suspending lambda so you should be able to invoke it there.
f
ctx.render("index", ejsArgs).await()
throws error when call middleware:
Copy code
server error TypeError: this.local$closure$ctx.render(...).await is not a function
    at Coroutine$foo$lambda$lambda.doResume (..\routes\node\index2.js:32:87)
Do you know if this might break in future or kotlin/JS implicitly add
await
?
@Evan R. without
await()
work but if I add
await
throws error in middleware call.
e
Does it know you’re calling the coroutine extension function as opposed to a method on the return value? You may need to import the extension function:
import kotlin.js.Promise.await
f
@Evan R. I try and same error. I understand
ctx.render()
is variable of Koa.js and it will never have
await()
function of coroutines. ¿I need add await() in promise or another coroutine class?
e
If ctx.render() returns a promise, you should be able to call the
Promise.await()
extension function on it. That’s what extension functions do — they can be called on a type without creating a new subclass
Does this work?
Copy code
router.get("/index2") { ctx, next ->
        GlobalScope.promise {
            val renderPromise: Promise<Any> = ctx.render("index", ejsArgs)
            renderPromise.await()
        }
 }
👍 1
f
@Evan R. Yes thx, Work middleware call. Kotlin generate this JS:
Copy code
var await_0 = $module$kotlinx_coroutines_core.kotlinx.coroutines.await_t11jrl$;

function(){
  ............
var renderPromise = this.local$closure$ctx.render('index', this.local$closure$ejsArgs);
            this.state_0 = 2;
            this.result_0 = await_0(renderPromise, this);
  .............
}
I hope it does not break in the future.
@Evan R.,Do you know of any book or guide for coroutines in Kotlin/JS? Coroutines in kotlin/Js are different than kotlin/jvm.
e
The only way coroutines are different on JS as opposed to the JVM is the fact that when working with JS libraries you may need to use the coroutine bridges to interact with promises. Otherwise everything else is the same, you can write suspending functions and start coroutines via
GlobalScope.launch {}
or
runBlocking {}
just like you can on the JVM By coroutine bridges, I mean these extension functions: • https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/kotlin.js.-promise/index.htmlhttps://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/promise.html
f
Ok, I will check it.
a
you can’t use
runBlocking
in JS, because there’s no blocking in JS
e
My bad, I didn’t read the docs closely enough