I'm trying to catch any error cases in the ViewModel and update the UIState, but it's not working.
This is the sealed interface to handle the different responses:
sealed interface UniversalisUiState {
data object Loading : UniversalisUiState
data class UniversalisData(
val selectedTopicId: String,
val topics: UniversalisResource,
) : UniversalisUiState
data object Empty : UniversalisUiState
data class UniversalisError(
val message: String,
) : UniversalisUiState
}
In the ViewModel the relevant code is:
val uiState: StateFlow<UniversalisUiState> = combine(
selectedTopicId,
getUniversalisUseCase.invoke(
date = selectedDate.value,
title = route.initialTopicId!!,
selectedTopicId = LiturgyHelper.liturgyByName(route.initialTopicId!!)
.toString()
).catch {
//NOT WORKING *******
//emit(UniversalisUiState.UniversalisError(it.message))
Timber.d("aaa", it.message)
},
UniversalisUiState::UniversalisData,
).stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = Loading,
)
And in the UseCase:
class GetUniversalisUseCase @Inject constructor(
private val universalisRepository: UniversalisRepository,
private val userDataRepository: UserDataRepository,
) {
operator fun invoke(
date: Int,
selectedTopicId: String,
title: String
): Flow<UniversalisResource>
{
return combine(
userDataRepository.userData,
universalisRepository.getUniversalisByDate(
UniversalisResourceQuery(
filterDate = date,
selectedTopic = selectedTopicId.toInt()
)
),
) { userData, universalis ->
if (universalis.todayDate == 0 && selectedTopicId != "30") {
universalisRepository.insertFromRemote(
UniversalisResourceQuery(
date,
selectedTopicId.toInt()
)
)
}
UniversalisResource(
date = universalis.todayDate,
title = title,
name = "",
id = selectedTopicId.toInt(),
data = universalis,
dynamic = userData
)
}
}
}
How I can do this: emit(UniversalisUiState.UniversalisError(it.message))
when catching errors? I can see de error of Timber
, but I can't emit UniversalisError
.
I'm trying to catch any error cases in the ViewModel and update the UIState, but it's not working.
This is the sealed interface to handle the different responses:
sealed interface UniversalisUiState {
data object Loading : UniversalisUiState
data class UniversalisData(
val selectedTopicId: String,
val topics: UniversalisResource,
) : UniversalisUiState
data object Empty : UniversalisUiState
data class UniversalisError(
val message: String,
) : UniversalisUiState
}
In the ViewModel the relevant code is:
val uiState: StateFlow<UniversalisUiState> = combine(
selectedTopicId,
getUniversalisUseCase.invoke(
date = selectedDate.value,
title = route.initialTopicId!!,
selectedTopicId = LiturgyHelper.liturgyByName(route.initialTopicId!!)
.toString()
).catch {
//NOT WORKING *******
//emit(UniversalisUiState.UniversalisError(it.message))
Timber.d("aaa", it.message)
},
UniversalisUiState::UniversalisData,
).stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = Loading,
)
And in the UseCase:
class GetUniversalisUseCase @Inject constructor(
private val universalisRepository: UniversalisRepository,
private val userDataRepository: UserDataRepository,
) {
operator fun invoke(
date: Int,
selectedTopicId: String,
title: String
): Flow<UniversalisResource>
{
return combine(
userDataRepository.userData,
universalisRepository.getUniversalisByDate(
UniversalisResourceQuery(
filterDate = date,
selectedTopic = selectedTopicId.toInt()
)
),
) { userData, universalis ->
if (universalis.todayDate == 0 && selectedTopicId != "30") {
universalisRepository.insertFromRemote(
UniversalisResourceQuery(
date,
selectedTopicId.toInt()
)
)
}
UniversalisResource(
date = universalis.todayDate,
title = title,
name = "",
id = selectedTopicId.toInt(),
data = universalis,
dynamic = userData
)
}
}
}
How I can do this: emit(UniversalisUiState.UniversalisError(it.message))
when catching errors? I can see de error of Timber
, but I can't emit UniversalisError
.
1 Answer
Reset to default 1Since you want to emit a UniversalisUiState
, you need to move the catch
after the combine, when the flow is already of that type:
val uiState: StateFlow<UniversalisUiState> = combine(
selectedTopicId,
getUniversalisUseCase.invoke(
date = selectedDate.value,
title = route.initialTopicId!!,
selectedTopicId = LiturgyHelper.liturgyByName(route.initialTopicId!!)
.toString()
),
UniversalisUiState::UniversalisData,
).catch<UniversalisUiState> {
emit(UniversalisUiState.UniversalisError(it.message))
Timber.d("aaa", it.message)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = UniversalisUiState.Loading,
)
You might need to explicitly specify the interface UniversalisUiState
as the generic type of catch, so Kotlin can correctly infer the type of the resulting flow.