make onCreateView suspend

I have a Flow in my fragment.

in onCreateView, I am using flow.first().element to initiate some UI elements.

But it gives me this error: Suspend function 'first' should be called only from a coroutine or another suspend function > make onCreateView suspend.

First of all, I’m not sure that’s a good idea (lol) but making onCreateView suspend gives me a plethora of more problems.

I’m pretty new to kotlin flows so I’m not entirely sure how stuff works, so any insight on what I should do in this situation is well appreciated!

Note: I really just want to access the value in my flow, so if there are other ways that help me with accessing them, that works too!

  • onCreateView run on UI thread so you are not allowed to block it. Don’t you start collecting your flow value in onViewCreated according to MVVM pattern? Why the need to use flow.first to put it in view during creation?

    – 




If you’re using flow.first() in your fragment, you’re probably doing something wrong. Why are you using a Flow if it only has a single useful value? Flows are typically collected to work with their series of data as they arrive. The first() function might be used for multi-purpose flows where there’s some specific case where you only care about the first value but in other cases you want multiple values.

If a Flow is involved, this suggests there is data that may not be initially available and takes some time to be ready.

Usually we create our views first and then fill in the data once it’s ready. onCreateView() is not intended for connecting data to views. You can just return the view with empty data. If you expect the flow to take a while to return the first useful value, you could put some kind of progress bar in your initial UI to indicate to the user that it’s in a loading state.

Then in onViewCreated(), launch a coroutine to collect the flow and connect it to your UI. You need to launch a coroutine to work with a flow properly. In between the time when you launch the coroutine and when the first value arrives, your UI will be left in its initial state. This is why you might consider showing a loading indicator. But if the data will arrive pretty quickly, that’s not necessary.

override fun onViewCreated() {
    super.onViewCreated()
    viewModel.someFlow
        .onEach { value ->
            // update UI with value
        }
        .flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)
        .launchIn(viewLifecycleOwner.lifecycleScope)
}

Leave a Comment