androidkotlinviewmodelkotlin-coroutinesandroid-paging-3

Multi page viewPager2 with paging 3 doesn't show data on page 2 using SharedViewModel


I want to implement two view tab, with recycle view as list, and using paging 3 for collecting data and return will be kotlin flow. everthing is working perfectly at tab one, but nothing show in tab two.

the viewModel code (SharedViewModel):

@ExperimentalPagingApi
@HiltViewModel
class MovieViewModel @Inject constructor(
    private val repository: MovieRepository,
    private val dispatcher: CoroutineDispatcher
) : ViewModel() {
    private val TAG = "MovieVM"


    private var _moviePaging: Flow<PagingData<MovieEntities>>? =
        repository.getMovie().cachedIn(viewModelScope)
    private var _tvPaging: Flow<PagingData<MovieEntities>>? =
        repository.getTv().cachedIn(viewModelScope)



    init {
        loadMovie()
    }

    // new paging
    var moviePaging = MutableStateFlow<PagingData<MovieEntities>>(PagingData.empty())
    var tvPaging = MutableStateFlow<PagingData<MovieEntities>>(PagingData.empty())

    private fun loadMovie() {
        viewModelScope.launch(dispatcher) {
            _moviePaging?.collectLatest {
                moviePaging.value = it
            }
            _tvPaging?.collectLatest {
                tvPaging.value = it
            }
        }
    }

the code is run. when i am debuging, only _moviePaging is call and show logger retrofit GET, but the _tvPaging is nothing, not call api, like never triggered to run (unreachable?)

so, i was change order, call _tvPaging first. then only _tvPaging is run.

I want two line of code _moviePaging and _tvPaging running, but now is just one of them. Please Help.

Any response will apreciate.


Solution

  • after reading some documentation, and understand about work flow coroutine,

    one coroutine scope for hot flow only one methode can run, they suspend forever

    so, the solution is make viewModelScope for each hot flow

    viewModelScope.launch(dispatcher) {
                _moviePaging?.collectLatest {
                    moviePaging.value = it
                }
            }
    viewModelScope.launch(dispatcher) {
                _tvPaging?.collectLatest {
                    tvPaging.value = it
                }
            }