Pablo
06/08/2024, 6:58 AMviewmodel with Flow and Room that connected my variables on the UiState with Room using .first() as the codelabs showed me. I noticed that using .first() is not a good idea because when I inserted something in the database, the screen didn't get refreshed automatically showing the new value. So I learned that using collect{} is the correct approach to continuously update the uistate variables automatically. After changing it now my screen is not showing any data and I can't disscover why. Please, can you help me trying to find where is the issue? I'm adding the viewmodel here.Pablo
06/08/2024, 6:59 AMdata class UiState(
val searchResult: List<Airport> = listOf(),
val favorites: List<Favorite> = listOf(),
val selectedAirport: Airport? = null,
val flightsForSelectedAirport: List<Airport> = listOf()
)
class FlightsScreenViewModel(
private val flightRepository: FlightsRepository,
private val userPreferencesRepository: UserPreferencesRepository
) : ViewModel() {
var uiState by mutableStateOf(UiState())
private set
var searchText by mutableStateOf("")
private set
init {
viewModelScope.launch {
// searchText = userPreferencesRepository.searchText.first()
userPreferencesRepository.searchText.collect{ searchText = it }
updateSearchResults()
}
}
private suspend fun updateSearchResults() {
// val searchResult = if (searchText != "")
// flightRepository.getAirportsByIatOrName(searchText).filterNotNull().first()
// else
// emptyList()
//
// val favorites = flightRepository.getFavorites().filterNotNull().first()
//
// uiState = uiState.copy(
// searchResult = searchResult,
// favorites = favorites
// )
if (searchText != "") {
flightRepository.getAirportsByIatOrName(searchText).filterNotNull().collect{ uiState = uiState.copy(searchResult = it) }
} else {
uiState = uiState.copy(favorites = emptyList())
}
flightRepository.getFavorites().filterNotNull().collect{ uiState = uiState.copy(favorites = it) }
}
fun updateSearchText(searchText: String) {
this.searchText = searchText
viewModelScope.launch {
userPreferencesRepository.saveSearchTextPreference(searchText)
updateSearchResults()
}
}
fun selectAirport(airport: Airport?) {
viewModelScope.launch {
// val flightsForSelectedAirport = if (airport == null) {
// emptyList()
// } else {
// flightRepository.getAllDifferentAirports(airport.id).first()
// }
//
// uiState = uiState.copy(
// selectedAirport = airport,
// flightsForSelectedAirport = flightsForSelectedAirport
// )
if (airport != null) {
flightRepository.getAllDifferentAirports(airport.id).collect{ uiState = uiState.copy(flightsForSelectedAirport = it) }
} else {
uiState = uiState.copy(flightsForSelectedAirport = emptyList())
}
uiState = uiState.copy(selectedAirport = airport)
}
}
fun insertFavorite(depart: String, arrive: String) {
if (!uiState.favorites.checkIfFavoriteExists(depart, arrive)) {
val favorite = Favorite(departureCode = depart, destinationCode = arrive)
viewModelScope.launch {
flightRepository.insertFavorite(favorite)
}
}
}
companion object {
val factory : ViewModelProvider.Factory = viewModelFactory {
initializer {
FlightsScreenViewModel(
FlightSearchApplication().container.flightRepository,
FlightSearchApplication().container.userPreferencesRepository
)
}
}
}
}
fun List<Favorite>.checkIfFavoriteExists(depart: String, arrive: String): Boolean{
for (favorite in this){
if (favorite.departureCode == depart && favorite.destinationCode == arrive)
return true
}
return false
}Pablo
06/08/2024, 7:03 AMLazyColumn(
modifier = Modifier.padding(8.dp)
) {
items(uiState.searchResult) { airport ->
AirportDetail(airport, onAirportSelected)
}
}
uiState.selectedAirport?.let {
FlightsForAirport(
airport = uiState.selectedAirport,
arrivals = uiState.flightsForSelectedAirport,
favorites = uiState.favorites,
onFavoriteSelected = onFavoriteSelected
)
}lesincs
06/08/2024, 11:46 AMupdateSearchResults function, you have two flow.collect() in same suspend function which would be dangerous as for some types of flow mostly hot flow like StateFlow or SharedFlow, the collect() suspends there forever until got canceled. So that might be the reason.