0

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)
     

    } 
}
DevPeter
  • 83
  • 2
  • 8

1 Answers1

1

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

Steyrix
  • 2,796
  • 1
  • 9
  • 23
  • Thank you for your answer. The real app will have for example Customer entity, an Order entity that may or have not have an order for that specific customer and specific day and another 10 entities with 3,000 records each that I have to consider. I was hoping that the MediatorLiveData can somehow filter each Live/Flow data by comparing if the customer id exists for each entity and then take out information that I need to decide what viewTypeId the customer should use at the end and send information to the activity to observe. – DevPeter Nov 11 '22 at 19:37