If I'm using `Flow` as the bridge between a VM and...
# android
k
If I'm using
Flow
as the bridge between a VM and a fragment, how can I ensure that the callback I use for the flow is initialized before I need It? The way I'm approaching it now seems like an antipattern.
Copy code
private var loadedPosts: List<Post> = emptyList()
    private lateinit var loadedPostsCallback: LoadedPostsCallback
    val posts: Flow<List<Post>> = callbackFlow {
        val callback = object : LoadedPostsCallback {
            override fun setLoadedPosts(posts: List<Post>) {
                loadedPosts = loadedPosts + posts
                offer(loadedPosts)
            }
        }
        loadedPostsCallback = callback

        awaitClose()
    }
when setting everything up in the fragment, I start a new coroutine to observe the
posts
. However, the
loadedPostsCallback
isn't initialized when I try to do the initial load from
loadPosts()
.
The idea I have right now is to
suspendCoroutine
until I can ensure everything is initialized correctly, but I feel like there's a better way
nevermind. Avoiding
callbackFlow
and using a backing channel of my own made this easier
d
Why can't you init
loadedPostsCallback
inside
callbackFlow
?
Yeah, was about to hint at that.
k
@Dominaezzz I did, but the flow wasn't actually being initialized because that block didn't get run until
collect
was being called
using my own backing channel makes it much easier to read too 😅
d
You could call
produceIn
and turn the flow into a channel.
k
I ended up with this
Copy code
private val postsChannel: Channel<List<Post>> = Channel(CONFLATED)
    val posts: Flow<List<Post>> = flow {
        postsChannel.consumeEach {
            loadedPosts = it
            emit(it)
        }
    }
and just use
Channel.offer
as the callback
d
Hmm, I feel like this could definitely be improved somehow.
k
yeah it definitely doesn't feel as easy as LiveData. There's got to be something I'm missing
d
You should be able to do this with,
callbackFlow {}.onEach {}.launchIn(coroutineScope)
.
k
not quite sure how to apply that to something like the snippit above
d
Can
loadedPostsCallback
be initialised and registered inside a flow? (Do you need a context or smth)
k
no, but I did need to make the callback from within the flow or else I wouldn't be able to offer in the flow scope
right?
d
Ah, I misread. Channel seems to be what you need.
k
cool 🙂