-
Notifications
You must be signed in to change notification settings - Fork 8
Part2.3
- 2.1 - Create the weather entity
- 2.2 - Write the Weather DAO and set up the Room database
- 2.3 - Update the weather repository and run
We are now ready! We can put all the Room components together to write an room version of our DailyForecastRepository
Let's create a new version of the DailyForecastRepositoryImpl
as a Room version: DailyForecastRepositoryRoomImpl
in package domain/repository
. Copy the DailyForecastRepositoryImpl
class and replace with the code below, which uses WeatherDAO
instead of local memory cache.
- Write constructor as follow:
class DailyForecastRepositoryRoomImpl(
private val weatherDatasource: WeatherDataSource,
private val weatherDAO: WeatherDAO
) : DailyForecastRepository {
- Remove
lastLocationFromCache()
function andweatherCache
property
Now, we need to rework functions as follow:
- Rewrite
getWeatherDetail()
function to use directly the DAO:
// Get weather from its id
override fun getWeatherDetail(id: String): Single<DailyForecast> =
weatherDAO.findWeatherById(id).map { DailyForecast.from(it) }
- Rewrite
getWeather()
as follow: use 2 functions (getNewWeather()
andgetWeatherFromLatest()
) and requests last weather or a new one:
// Get weather from latest or default one if the location is null
// else get new weather
override fun getWeather(
location: String?
): Single<List<DailyForecast>> {
return if (location == null) {
weatherDAO.findLatestWeather().flatMap { latest: List<WeatherEntity> ->
if (latest.isEmpty()) getNewWeather(DEFAULT_LOCATION) else getWeatherFromLatest(latest.first())
}
} else {
getNewWeather(location)
}
}
- Add the following
getNewWeather()
function to request a new weather for location:
// Get new weather and save it
private fun getNewWeather(location: String): Single<List<DailyForecast>> {
val now = Date()
return weatherDatasource.geocode(location)
.map { it.getLocation() ?: throw IllegalStateException("No Location date") }
.flatMap { weatherDatasource.weather(it.lat, it.lng, DEFAULT_LANG) }
.map { it.getDailyForecasts(location) }
.doOnSuccess { list ->
weatherDAO.saveAll(list.map { item -> WeatherEntity.from(item, now) })
}
}
- Add the
getWeatherFromLatest()
function which requests latest weather data:
// Find latest weather
private fun getWeatherFromLatest(latest: WeatherEntity): Single<List<DailyForecast>> {
return weatherDAO.findAllBy(latest.location, latest.date)
.map { list -> list.map { DailyForecast.from(it) } }
}
Now, the DailyForecastRepositoryRoomImpl
should compile! β
In room_datasource_module.kt
, add and override the DailyForecastRepository
definition for the new DailyForecastRepositoryRoomImpl
constructor (add an additional get()
to fill dependency for constructor, else you'll get a compilation error):
Add the following definition:
// Weather Room Data Repository
single<DailyForecastRepository>(override = true) { DailyForecastRepositoryRoomImpl(get(),get()) }
Note π: We keep both implementation of DailyForecastRepository
by using moduel configuration change. It also allow us to not break our tests.
- Uncomment
WeatherRepositoryTest
from Android test - Comment
datasource/WeatherRepositoryTest
from unit tests - Run all tests from Android test
WeatherRepositoryTest
- Run the weather app on your device!
Make sure all tests are passing (Unit & Android)!
The weather app now stores your last location. Kill the app and restart it. You should have your last location instead of the default "Paris" location.