Hi all, I’m wondering if there are any good exampl...
# compose
k
Hi all, I’m wondering if there are any good examples out there showing how to load things off the main thread from inside a composable
m
Put your slow-running code in a coroutine running on a suitable dispatcher (e.g,.
<http://Dispatchers.IO|Dispatchers.IO>
) and use
LaunchedEffect
to consume the result. For example, I have a
load()
function that gets some data off the Internet.
load()
is marked with
suspend
, and the actual network I/O is done on a background thread (courtesy of Retrofit). I then use
LaunchedEffect
to update a
MutableState
with the results and use that to drive what to show in a screen:
Copy code
@Composable
private fun Body(office: String = "OKX") {
  var results: MainViewState by remember { mutableStateOf(MainViewState.Loading) }

  when (val content = results) {
    is MainViewState.Loading -> LoadingState()
    is MainViewState.Content -> ContentState(content)
    is MainViewState.Error -> ErrorState()
  }

  val context = LocalContext.current

  LaunchedEffect(key1 = office) {
    results = load(office, 32, 34, context)
  }
}
1
k
Hi, thanks for your reply. That’s the option I was going for after having read https://jorgecastillo.dev/jetpack-compose-effect-handlers I will definitely give it a try now
👍🏻 1
c
Is doing network requests in composables a thing? I thought they should be handed their data to display?
a
Depends on the layer. If you have a composable function
UrlImage(url: String, ...)
it's doing something to load that, and if you strip away any intermediate layers of abstraction around caching and testability of the network request/response, it'll probably look a lot like the above.
👍 1
c
Interesting. I was working on my own little stock ticker composable where you give the composable a string like GOOG for example and then it would go off and load a little mini chart next to the name (similar to Robinhood). But I reverted my work. Now I'm thinking though... That doesn't sound too terrible.
a
"doing network requests in your composables" will generally elicit a 😬, but passing an image URL to a composable that then consults an appropriately scoped image cache/repository, which may kick off a network fetch if the requested resource is missing or stale? 🤷‍♂️ Something has to initiate that work somewhere.
"appropriately scoped" is generally the key. For the case you describe, you'd probably have some sort of repository object that you pass along with your ticker string, and the composable might fetch a flow from that object based on the ticker and collect it
You don't necessarily want to kick off a new network refresh with no other context any time an instance of that composable enters the composition, you want to pull out your source of data
Flow.collectAsState
is just a
LaunchedEffect
that looks a lot like the example above under the hood