Search code examples
androidkotlinandroid-roomkotlin-flow

Update (or create) flow inside itself and emit this, Room, Flow, MVVM


I have been creating an SMS app. I have a list of conversations stored in Room database as ConversationEntity.

This is my query:

@Query("SELECT * FROM conversation_entity ORDER BY timestamp DESC")
fun getAllConversations(): Flow<List<ConversationEntity>>

I would like to observe (collect) data from this query inside my repository class, but I have to map it to a List<Conversation>. I know how to collect this data, I known to map List<ConversationEntity> into List<Conversation>. But I have no idea how should I emit list of conversations?

I tried things like emit second flow from the first one, or use MutableStateFlow and set date by .value


Solution

  • I am still confused what you mean, since you said you know how to collect a Flow and how to map List to List. So anyway let me give it a try:

    class DAO {
      @Query("SELECT * FROM conversation_entity ORDER BY timestamp DESC")
      fun getAllConversations(): Flow<List<ConversationEntity>>
    }
    
    class Repository(private val dao: Dao) {
      fun getConversations(): Flow<List<Converstaion>> {
        // this maps every emitted element of the flow
        return dao.getAllConversations.map { list: List<ConversationEntity> ->
          // and this maps every element in the list
          list.map { conversationEntity ->
            conversationEntity.mapToConversation()
          }
        }
      }
    }
    
    class ConversationMapper {
      // Maps ConversationEntity to Conversation
      fun ConversationEntity.mapToConversation(): Conversation {
        // I have no idea of the fields, so you have to implement this mapping function yourself.
        return Converation(...)
      }
    }
    

    And that's it. Here is how you can use it in your ViewModel:

    class YourViewModel : ViewModel(private val repository: Repository) {
      val converstationLiveData: LiveData = repository.getConversations().toLiveData()
    }
    
    Hope that helps you. But if this is still not what you meant, then please update your question accordingly.