Rafa Gómez
03/03/2024, 7:08 PMclass AgendaViewModel(
api: AgendaAPI
) : ViewModel() {
private val searchAgenda = AgendaSearcher(api)
private val bookAgenda = AgendaBooker(api)
private val cancelAgenda = AgendaCanceler(api)
private val internalState = MutableStateFlow(AgendaViewModelState())
init {
// Perform initial search operation to populate the state
viewModelScope.launch {
val initialAgendas = searchAgenda.invoke2(9, 24)
internalState.update { it.copy(agendas = initialAgendas) }
}
}
val state = combine(
internalState,
searchAgenda(9, 24)
) { state, agendas -> state.copy(agendas = agendas) }
.stateIn(viewModelScope, WhileSubscribed(5000L), AgendaViewModelState())
}
Inside my state there's a list of agendas I'd like to get from my backend and use it as the initial state of my view model. I access the backend through a ktor client and using the following interface
interface AgendaAPI {
fun search(criteria: SearchAgendaCriteria): Flow<List<Agenda>>
suspend fun searchV2(criteria: SearchAgendaCriteria): List<Agenda>
}
I've tried both options (flow and suspend with direct result), the block inside the init method returns an initial agenda with 7 values but then it's not updated as a state. Whenever I create the view model from the app and call the composable it's still an empty list of agendas.
@Composable
fun App() {
initKoin()
val mainScope = MainScope()
val restClientClient = RestClient()
val agendaClient = RestAgendaClient(restClientClient)
val api = RestAgendaAPI(agendaClient)
MaterialTheme {
val viewModel = getViewModel(
key = "agendas-view-screen",
factory = viewModelFactory {
AgendaViewModel(api)
}
)
val state by viewModel.state.collectAsState()
AgendaListScreen(state, viewModel::onEvent)
}
}
I'm pretty sure I'm doing something wrong here, does anyone know what is it? Any other improvements or tips are also welcomed.
Not 100% sure if this is the right place though but I'd highly appreciate the any help.Sean Proctor
03/03/2024, 9:59 PMinit
seems pretty useless currently because it just updates a value that is never used (since your agendas
is always set by to the result from searchAgenda(9, 24)
in the combine
. I would create your public state like val state: StateFlow<AgendaViewModelState> = internalState
since you already have a backing StateFlow
that you're updating.