How can I handle multiple parameters when I use combin function in Kotlin

I know that the combin function accepts the max 5 parameters, so I have to use .combine( ){ }.combine( ){ } in my Code A.

I think the Code A is not good way.

Code B is a optimized code.

1: Code C is modified by me, is it correct?

2: Is there the better way to handle to multiple parameters for combine function?

Code A

data class HomeUIState(
    val loadingDataResult: EResult<List<MInfo>> = EResult.LOADING,
    val recordingState: ERecordState = ERecordState.STOPPED,
    val eSortBy: ESortBy = ESortBy.START_PRIORITY,

    val elapsedTime: String="00:00:00",

    val expandedListMInfoID: List<Int> = emptyList(),

    val playingMInfo: MInfo = MInfo(),
    val playState: EPlayState = EPlayState.STOPPED,

    val locateRecordID: Int = -1
)

private val _recordingState= MutableStateFlow(ERecordState.STOPPED)
    private val _eSortBy = MutableStateFlow(ESortBy.START_PRIORITY)
    private val _loadingDataResult = _eSortBy.flatMapLatest { handelMInfo.listAll(it)}
                                        .stateIn(
                                             viewModelScope,
                                             SharingStarted.WhileSubscribed(),
                                             EResult.LOADING
                                          )
    private val _elapsedTime = MutableStateFlow("00:00:00")
    private val _expandedListMInfoID = MutableStateFlow(emptyList<Int>())
    private val _playingMInfo = MutableStateFlow(MInfo())
    private val _playState = MutableStateFlow(EPlayState.STOPPED)
    private val _locateRecordID = MutableStateFlow(-1)
  
    val homeUIState: StateFlow<HomeUIState> =  combine(
        _loadingDataResult, _recordingState, _eSortBy, _elapsedTime, _expandedListMInfoID
    ) {
        loadingDataResult, recordingState, eSortBy, elapsedTime, expandedListMInfoID  ->

        val basedHomeUIState = HomeUIState(
            recordingState = recordingState,
            eSortBy = eSortBy,
            elapsedTime = elapsedTime,
            expandedListMInfoID = expandedListMInfoID
        )

        when (loadingDataResult) {
            is EResult.LOADING -> {
                basedHomeUIState.copy(loadingDataResult = EResult.LOADING)
            }

            is EResult.SUCCESS -> {
                basedHomeUIState.copy(
                    loadingDataResult = EResult.SUCCESS(loadingDataResult.data)
                )
            }

            is EResult.ERROR -> {
                basedHomeUIState.copy(loadingDataResult = EResult.ERROR(loadingDataResult.exception))
            }
        }
    }.combine(_playingMInfo) {
        homeUIState, playingMInfo -> homeUIState.copy(playingMInfo = playingMInfo)
    }.combine(_playState) {
        homeUIState, playState -> homeUIState.copy(playState = playState)
    }.combine(_locateRecordID) {
        homeUIState, locateRecordID -> homeUIState.copy(locateRecordID = locateRecordID)
    }
        . stateIn(
           viewModelScope,
           SharingStarted.WhileSubscribed(),
           HomeUIState()
        )

Code B

private val _recordingState = MutableStateFlow(ERecordState.STOPPED)
...

private val baseHomeUIState: StateFlow<HomeUIState> = combine(
    _recordingState,
    _eSortBy,
    _elapsedTime,
    _expandedListMInfoID
) { recordingState, eSortBy, elapsedTime, expandedListMInfoID ->
    HomeUIState(
       ...
    )
}.stateIn(
    viewModelScope,
    SharingStarted.WhileSubscribed(),
    HomeUIState()
)

val homeUIState: StateFlow<HomeUIState> = combine(
    baseHomeUIState,
    _loadingDataResult,
    _playingMInfo,
    _playState,
    _locateRecordID
) { baseState, loadingDataResult, playingMInfo, playState, locateRecordID ->
    when (loadingDataResult) {
        is EResult.LOADING -> baseState.copy(loadingDataResult = EResult.LOADING)
        is EResult.SUCCESS -> baseState.copy(loadingDataResult = EResult.SUCCESS(loadingDataResult.data))
        is EResult.ERROR -> baseState.copy(loadingDataResult = EResult.ERROR(loadingDataResult.exception))
    }.copy(
        playingMInfo = playingMInfo,
        playState = playState,
        locateRecordID = locateRecordID
    )
}.stateIn(
    viewModelScope,
    SharingStarted.WhileSubscribed(),
    HomeUIState()
)

Code C

   private val _recordingState= MutableStateFlow(ERecordState.STOPPED)
   ...   

    private val baseHomeUIState = combine(
        _recordingState,
        _eSortBy,
        _elapsedTime,
        _expandedListMInfoID
    ) { recordingState, eSortBy, elapsedTime, expandedListMInfoID ->
        HomeUIState(
          ...
        )
    }

    val homeUIState: StateFlow<HomeUIState> = combine(
        baseHomeUIState,
        _loadingDataResult,
        _playingMInfo,
        _playState,
        _locateRecordID
    ) { baseState, loadingDataResult, playingMInfo, playState, locateRecordID ->
        when (loadingDataResult) {
            is EResult.LOADING -> baseState.copy(loadingDataResult = EResult.LOADING)
            is EResult.SUCCESS -> baseState.copy(loadingDataResult = EResult.SUCCESS(loadingDataResult.data))
            is EResult.ERROR -> baseState.copy(loadingDataResult = EResult.ERROR(loadingDataResult.exception))
        }.copy(
            playingMInfo = playingMInfo,
            playState = playState,
            locateRecordID = locateRecordID
        )
    }.stateIn(
        viewModelScope,
        SharingStarted.WhileSubscribed(),
        HomeUIState()
    )

  • FYI, it’s against the rules to post AI-generated content and it might get your question closed.

    – 

  • IMO, I would use a single Flow of some data class that has all the information to begin with so you don’t have to combine them.

    – 

  • Thanks! How can I use single Flow of some data to do this? Could you give me some sample code ? You know there is a data class HomeUIState(..) in my project.

    – 

Leave a Comment