How would I go from a suspending function to a Pro...
# javascript
j
How would I go from a suspending function to a Promise or just getting rid of the suspend completely? (on the JVM, you would use runBlocking for example) My submit function is using Coroutines, but I want to JsExport the functions making use of the submit function
Copy code
class POST(
	val uri: String,
	val json: String,
) {

	suspend fun <T> submit(): T {
		return window.fetch(
			input = "${ENV.server}$uri",
			init = RequestInit(
				body = json,
				method = "POST",
				headers = json("content-type" to "application/json; charset=UTF-8"),
			)
		).await().json().await().unsafeCast<T>()
	}

}
Copy code
@JsExport
@ExperimentalJsExport
object Data {
	suspend fun getColumns(request: ColumnRequestVO): ColumnResponseVO {
		return POST(uri = "/columns", json = request.toString()).submit<ColumnResponseVO>()
	}
}
Declaration of such kind (suspend function) cant be exported to JS
v
Iirc a suspending function will return a
Deferred
that has a
toPromise()
function or something like that.
j
Copy code
fun <T> submit(): Promise<T> {
		return GlobalScope.async {
			window.fetch(
				input = "${ENV.server}$uri",
				init = RequestInit(
					body = json,
					method = "POST",
					headers = json("content-type" to "application/json; charset=UTF-8"),
				)
			).await().json().await().unsafeCast<T>()
		}.asPromise()
	}
that returns a
kotlin.js.Promise
which seems to be almost where I want to be, not sure how to await that in TypeScript
Exported declaration uses non-exportable return type: Promise<T>
t
“non-exportable”
Promise
- bug. Issue required
j
this works:
Copy code
class POST(
	val uri: String,
	val json: String,
) {
	suspend fun <T> submit(): T {
		return window.fetch(
			input = "${ENV.server}$uri",
			init = RequestInit(
				body = json,
				method = "POST",
				headers = json("content-type" to "application/json; charset=UTF-8"),
			)
		).await().json().await().unsafeCast<T>()
	}
}
Copy code
fun getColumns(request: ColumnRequestVO): Promise<ColumnResponseVO> {
		return GlobalScope.async {
			POST(uri = "/columns", json = request.toString()).submit<ColumnResponseVO>()
		}.asPromise()
	}
and then on the TS side, I just need to use a callback
Copy code
export class ColumnSelector extends Renderable {

	constructor() {
		super();
		web.Data.getColumns(vo.ColumnRequestVO.create()).then(e => {
			console.log(e)
		})
thanks for the help!
a
You can say
GlobalScope.promise { }
instead of
GlobalScope.aysnc{ }.asPromise()
, although I think that’s just sugar
👀 2
🍻 1
✔️ 1
453 Views