I want to fetch some data when a button is pressed. I know how to do it using promises and continuations (see the sample below) but I'd like to learn how to do it using suspend functions.
As an example:
import kotlinx.browser.window
import react.FC
import react.Props
import react.dom.html.ReactHTML.button
import react.dom.html.ReactHTML.div
import react.useState
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
val MyComponent = FC<Props> {
var text by useState("Click Load")
div { +text }
button {
+"Load"
onClick = {
text = "Loading..."
window.fetch("https://catfact.ninja/fact").then { response ->
response.text().then { receivedText ->
text = receivedText
}
}
//text = fetchCat() //This line does not compile
}
}
}
suspend fun fetchCat() = suspendCoroutine<String> { continuation ->
window.fetch("https://catfact.ninja/fact")
.then { response ->
response.text()
.then { text -> continuation.resume(text) }
.catch { continuation.resumeWithException(it) }
}
.catch { continuation.resumeWithException(it) }
}
A reference to kotlinx.coroutines
needs to be added to gradle:
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
Then a MainScope is created globally (a single instance is used for the whole application), using which suspend functions can be called.
import kotlinx.browser.window
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import react.FC
import react.Props
import react.dom.html.ReactHTML.button
import react.dom.html.ReactHTML.div
import react.useState
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
val mainScope = MainScope()
val MyComponent = FC<Props> {
var text by useState("Click Load")
div { +text }
button {
+"Load"
onClick = {
text = "Loading..."
mainScope.launch {
text = fetchCat()
}
}
}
}
suspend fun fetchCat() = suspendCoroutine { continuation ->
window.fetch("https://catfact.ninja/fact")
.then { response ->
response.text()
.then { text -> continuation.resume(text) }
.catch { continuation.resumeWithException(it) }
}
.catch { continuation.resumeWithException(it) }
}