I have three Room entities. An entity Person includes id and name, entity Holiday includes id, personId, onHoliday and Sickness entity includes id, personId and onSickness.
Also, I have a POJO Entity called ScreenPOJO that includes viewTypeId and personName.
My goal is to get the person's name (from Person) and viewTypeId that I can observe in Activity.
The viewTypeId is an Integer that depends on the onHoliday - true/false and onSickness true/false. So let's say when the onHoliday is false and onSickness is false the viewTypeId = 1, when onHoliday is true then viewTypeId = 2 and when onSickness is true then viewTypeId = 2.
In this example, it is achievable by creating a query and returning the result by using the POJO Entity.
Sometimes the query can be too complex and for that reason, I would like to somehow merge all three Live/Flow data together using the person_id. I read that I can use MediatorLiveData, however, I do not have experience yet to put all the data together and return only the result that I need (person name and viewTypeId).
Person Entity:
@Entity(tableName = "person_table")
data class Person(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id") val id: Int,
@SerializedName("name")
@ColumnInfo(name = "name") val name: String,
)
Sickness Entity:
@Entity(tableName = "sickness_table")
data class Sickness(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id") val id: Int,
@SerializedName("person_id")
@ColumnInfo(name = "person_id") val personId: Int,
@SerializedName("on_sickness")
@ColumnInfo(name = "on_sickness") val onSickness: Boolean
)
Holiday Entity:
@Entity(tableName = "holiday_table")
data class Holiday(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id") val id: Int,
@SerializedName("person_id")
@ColumnInfo(name = "person_id") val personId: Int,
@SerializedName("on_holiday")
@ColumnInfo(name = "on_holiday") val onHoliday: Boolean
)
ScreenPOJO Entity:
data class ScreenPOJO(
val viewTypeId: Int,
val personName: String
)
ViewModel, the data are originally as Flow :
val allPersons: LiveData<List<Person>> = repository.allPersons.asLiveData()
val allHolidays: LiveData<List<Holiday>> = repository.allHolidays.asLiveData()
val allSickness: LiveData<List<Sickness>> = repository.allSickness.asLiveData()
ViewModel, example of insert Person:
private val _insertPersonStatus = MutableLiveData<ViewModelStatus>()
val insertPersonStatus: LiveData<ViewModelStatus> = _insertPersonStatus
fun insertPerson(person: Person) = viewModelScope.launch {
try {
val insertedRowId = repository.insertPerson(person)
if (insertedRowId > -1) {
_insertPersonStatus.postValue(ViewModelStatus.SUCCESS(insertedRowId,ViewModelStatus.SUCCESS.Type.VM_INSERT))
} else {
_insertPersonStatus.value = ViewModelStatus.FAIL("Fail",ViewModelStatus.FAIL.Type.VM_INSERT)
}
} catch (ex: Exception) {
_insertPersonStatus.value = ViewModelStatus.EXCEPTION(ex.localizedMessage.toString(),ViewModelStatus.EXCEPTION.Type.VM_INSERT)
}
}
I think it is better to modify the data layer in a way, which will allow you to write less code in the business-logic and view layers, therefore the code will be simpler and cleaner which is always a good sign.
Therefore, instead of merging LiveData you should think about redesigning Person data class.
Since I don't see much sense in storing holidays and sickness separately from persons, I assume you should somehow store holiday and sickness related data in the person object. I suggest something like this (I will omit room annotations for simplicity):
data class Person(
val id: Long,
val name: String,
val onHoliday: Boolean,
val onSickness: Boolean
)
In case when the person has multiple holidays or sickness days, you can do something like this (which is kinda common practice nowadays):
data class Person(
val id: Long,
val name: String,
val holidays: List<Holiday>,
val sicknessDays: List<Sickness>
)
I am not sure that it is easy to insert a collection in Room, but there are workarounds here. Maybe you will also need @Embedded annotation to keep the POJO's inside of the POJO