I have a repository class:
class RepositoryImpl(private val application: Application) :
Repository {
override suspend fun getCities(): Resource<List<City>> =
try {
val bufferReader = application.assets.open(CITIES_FILE_NAME).bufferedReader()
val data = bufferReader.use {
it.readText()
}
val gson = GsonBuilder().create()
val type: Type = object : TypeToken<ArrayList<City?>?>() {}.type
val fromJson = gson.fromJson<List<City>>(data, type)
Resource.Success(fromJson)
} catch (e: JsonSyntaxException) {
Resource.Error(JSONSYNTAXEXCEPTION_ERROR_MESSAGE)
} catch (e: IOException) {
Resource.Error(IOEXCEPTION_ERROR_MESSAGE)
}
and the Resource
class is:
sealed class Resource<T>(
val data: T? = null,
val message: String? = null
) {
class Success<T>(data: T) : Resource<T>(data)
class Loading<T>(data: T? = null) : Resource<T>(data)
class Error<T>(message: String, data: T? = null) : Resource<T>(data, message)
}
I need to fetch the cities and I do it in my VM like this:
class CityListViewModel(private val repository: Repository) : ViewModel() {
@VisibleForTesting
val allCities: LiveData<Resource<List<City>>> =
liveData(context = viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
val cities: Resource<List<City>> = repository.getCities().sortedBy { city: City -> city.name }
emit(cities)
}
}
The problem, is that I modeled my repository to wrap the list of cities in a Resource
and I need to sort the cities alphabetically, so the line val cities: Resource<List<City>> = repository.getCities().sortedBy { city: City -> city.name }
does not compile.
Am I doing it wrong like this? The repository just takes care of retrieving the data and wrapping it in the Resource
and the business logic lies in the VM, but now it receives a Resource
and needs to access the data, sort it, and put it back in the Resource
so the Activity
knows what to do depending on the whether it's a Success
, Error
or Loading
.
Thanks a lot!
You can map your data before emiting to the UI:
...
emit(Resource.Loading())
val resource = repository.getCities().map {
if (it is Resource.Success) {
Resource.Success(it.data.sortedBy { city: City -> city.name })
} else {
it
}
}
emit(resource)
...