Reputation: 565
I am having a DB populated with weather data, in both imperial and metric units. Now, I have made two different classes which act as a model to get data from the DB. CurrentWeatherMetric
has only metric columns, and CurrentWeatherImperial
has only imperial fields.
Since I am using MVVM architecture pattern, the ViewModel
provides me this data, by calling a function in ViewModel getData(Unit.METRIC)
where Unit
is an enum class
I've made to distinguish the data.
The problem arises here. My viewModel looks like:
class WeatherViewModel(
private val weatherRepository: WeatherRepositoryImpl
) : ViewModel() {
lateinit var currentWeather: LiveData<CurrentWeather>
lateinit var forecastWeather: LiveData<List<ForecastWeather>>
fun getValuesOfUnit(unit: Unit) {
currentWeather = when (unit) {
Unit.IMPERIAL->weatherRepository.getCurrentWeatherImperial()
Unit.METRIC->weatherRepository.getCurrentWeatherMetric()
}
getWeather()
}
private fun getWeather() {
viewModelScope.launch {
try {
weatherRepository.getWeather()
} catch (e: IOException) {
}
}
}
}
As you can see, lateinit var currentWeather: LiveData<CurrentWeather>
,
I had to make another class which store the data of the query with units. I made this so that I could easily implement databinding with it. But I feel this is a really wrong way to do things and hence I have asked this question. How can I get rid of that lateinit
variable and implement databinding to adapt to any of the data.
In my current data binding layout, I have data field as:
<data>
<variable
name="viewModel"
type="com.mythio.weather.ui.WeatherViewModel" />
</data>
And I bind to views by:
app:someattribute="@{viewModel.currentWeather.temperature}"
If the question title makes a little sense about what I am asking, or seems misleading, please feel free to edit this to make it a better question.
Upvotes: 1
Views: 588
Reputation: 12128
When using MVVM architecture pattern, Google's recommended way is to make ViewModel
that handles connection between your data and view, so it contains UI logic as well as some portion of business logic bound to your UI.
Moreover, implementation of ViewModel
in recommended way helps you handle UI lifecycle (Activity/Fragments) in better and hassle-free way.
When using data-binding with MVVM, it's good practice to bind ViewModel
directly to xml so that, when data changes you can directly reflect it to UI using LiveData
without wiring it manually.
Hence, LiveData
can be used as Data-Value holder as it's also Lifecycle-aware component.
On the other hand, Repositories are good way to manage business logic and providing "single source of truth" for data driving through app. So, all data sources like local-db, API calls, shared-preferences etc. should be accessed via repository.
So, yes!! Things you're doing are good & you're on the right track while following MVVM Architecture Pattern.
Note: You can refer here for more info and some improvements in your code.
Upvotes: 1