Skip to content

Part2.3

Arnaud Giuliani edited this page Apr 4, 2018 · 25 revisions

Steps



2.3 - Update the weather repository and run

We are now ready! We can put all the Room components together to update our WeatherRepository


TODO 🎯 - update the WeatherRepositoryImpl class

Let's rewrite the WeatherRepositoryImpl class. Just replace the class with the code below, which uses WeatherDAO instead of local memory cache.

  • WeatherRepositoryImpl constructor is now:
class WeatherRepositoryImpl(
    private val weatherDatasource: WeatherWebDatasource,
    private val weatherDAO: WeatherDAO
) : WeatherRepository {
  • Remove lastLocationFromCache() and weatherCache property
  • getWeatherDetail use directly the DAO:
	 // Get weather from its id
    override fun getWeatherDetail(id: String): Single<DailyForecastModel> =
        weatherDAO.findWeatherById(id).map { DailyForecastModel.from(it) }
  • getWeather() is now based on 2 functions (getNewWeather() and getWeatherFromLatest()) 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<DailyForecastModel>> {
        return if (location == null) {
            weatherDAO.findLatestWeather().flatMap { latest: List<WeatherEntity> ->
                if (latest.isEmpty()) getNewWeather(DEFAULT_LOCATION) else getWeatherFromLatest(latest.first())
            }
        } else {
            getNewWeather(location)
        }
    }
  • the getNewWeather() which requests a new weather for location:
    // Get new weather and save it
    private fun getNewWeather(location: String): Single<List<DailyForecastModel>> {
        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) })
            }
    }
  • getWeatherFromLatest() which requests latest weather data:
    // Find latest weather
    private fun getWeatherFromLatest(latest: WeatherEntity): Single<List<DailyForecastModel>> {
        return weatherDAO.findAllBy(latest.location, latest.date)
            .map {
                it.map { DailyForecastModel.from(it) }
            }
    }

TODO 🎯 - Update Koin configuration:

In app_module.kt, update the definition for the new WeatherRepositoryImpl constructor (add an additional get() to fill dependency for constructor):

    // Weather Data Repository
    bean { WeatherRepositoryImpl(get(), get()) as WeatherRepository }

TODO 🎯 - Run last tests

  • Uncomment WeatherRepositoryTest from Android test
  • Comment datasource/WeatherRepositoryTest from unit tests
  • Run all tests from Android test WeatherRepositoryTest

Make sure all tests are passing (Unit & Android)


Congrats, You're done 👍 🍾

The weather app now stores your last location. Kill the app and restart it. You should have your last location stead of the default "Paris" location.

Clone this wiki locally