f

    Felipe Passos

    1 year ago
    Hello, how do i make this idea work : api.stream is reading a websocket, the idea is to update a variable every time it receives a websocket message.
    s

    Se7eN

    1 year ago
    You can use a lambda:
    suspend fun updateState(api: Api, onRecieve: (String) -> Unit) {
        val notify =  Channel<String>()
        api.stream(notify)
        while(true) {
            onRecieve(notify.receive())
        }
    }  
    
    @SuppressLint("CoroutineCreationDuringComposition")
    @Composable
    fun SomeComposable(api: Api, locationViewModel: LocationViewModel = viewModel()) {
        var state by remember { mutableStateOf("") }
        val composableScope = rememberCoroutineScope()
        composableScope.launch {
            updateState(api, onRecieve = { state = it })
        }
    }
    f

    Felipe Passos

    1 year ago
    This makes the api.stream goes on some loop and connect multiple times instead of one time and just reading
    s

    Se7eN

    1 year ago
    Oh yeah you need
    LaunchedEffect
    f

    Felipe Passos

    1 year ago
    What is this ?
    f

    Felipe Passos

    1 year ago
    What do i use as a key?
    Oh, get it
    s

    Se7eN

    1 year ago
    I guess you can use your api as the key since it will relaunch when your api changes
    Also, shouldn't the
    updateState
    be in your view model?
    f

    Felipe Passos

    1 year ago
    Any idea why it prints "" then the real state value ?
    s

    Se7eN

    1 year ago
    Because the initial value of your state is an empty string
    f

    Felipe Passos

    1 year ago
    Any way to the variable only holds the newer value ?
    I'm using the view model to store some coordinates that changes when the user click on a map
    s

    Se7eN

    1 year ago
    You can make the state null initially or maybe use a flow
    You can make another view model for your api stuff if you don't want it in the location view model
    f

    Felipe Passos

    1 year ago
    So a viewModel is better than a simple remember in this case?
    s

    Se7eN

    1 year ago
    From what I'm seeing, yes. It's always better to keep the UI separate
    Dominaezzz

    Dominaezzz

    1 year ago
    Should probably be
    fun updateState(api: Api): Flow<String>
    that returns a
    channelFlow { .... }
    . Then you can use
    collectAsState()
    .
    f

    Felipe Passos

    1 year ago
    What would be a snippet of this ? i never used a channelFlow before
    Dominaezzz

    Dominaezzz

    1 year ago
    fun updateState(api: Api): Flow<String> {
        return channelFlow<String> {
            api.stream(this)
            awaitClose { /* do closing things if needed */ }
        }
    }
    @SuppressLint("CoroutineCreationDuringComposition")
    @Composable
    fun SomeComposable(api: Api, locationViewModel: LocationViewModel = viewModel()) {
        val state by remember(api) { updateState(api) }.collectAsState("")
        // do stuff with state
    }
    f

    Felipe Passos

    1 year ago
    I saw here that it is a experimental api, is this safe to use ?
    Dominaezzz

    Dominaezzz

    1 year ago
    It was stabilised in the latest release so don't worry about it.
    f

    Felipe Passos

    1 year ago
    Ok, thank you all !