Search code examples
androidkotlinandroid-viewmodel

How to dynamically pass parameters in the Android ViewModel?


In the following variables, how do I dynamically pass user.id and friend.id


class WindViewModel @Inject constructor() : BaseViewModel() {

    val userWindList = Pager(config = pagingConfig, remoteMediator = WindRemoteMediator("userWindList", user.id, friend.id, database!!, api)) {
        windRepository.pagingModelList(friend.id, "userWindList")
    }.flow.map { pagingData ->
        pagingData.map { it.json.toWind() }
    }.cachedIn(viewModelScope)
}


Solution

  • I am assuming you specifically mean how to base a Flow on dynamically passed-in values.

    I have not used Paging, so I'm not 100% sure this is correct. Specifically, I don't know if is OK to swap to a different Pager source in the same Flow.

    But assuming it is OK, one way is to use a MutableSharedFlow as a base for the flow, and use flatMapLatest on it. You can dynamically change the parameters that your Flow is based on by emitting to the MutableSharedFlow.

    data class WindRemoteMediatorParams(val userId: String, val friendId: String) // helper class
    
    private val mediatorParams = MutableSharedFlow<WindRemoteMediatorParams>(replay = 1)
    
    @OptIn(ExperimentalCoroutinesApi::class)
    val userWindList = mediatorParams.flatMapLatest { (userId, friendId) ->
        Pager(config = pagingConfig, remoteMediator = WindRemoteMediator("userWindList", userId, friendId, database!!, api)) {
            windRepository.pagingModelList(friend.id, "userWindList")
        }.flow
    }.map { pagingData ->
        pagingData.map { it.json.toWind() }
    }.cachedIn(viewModelScope)
    
    fun beginPaging(userId: String, friendId: String) {
        mediatorParams.tryEmit(WindRemoteMediatorParams(userId, friendId))
    }