0

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

General Grievance
  • 4,555
  • 31
  • 31
  • 45
rogalz
  • 80
  • 8
  • I do not understand your question. Your query already gives you a flow of a list of `ConversationEntity`. So what is the problem here? Does it not work like this? Do you want to do mapping on the flow or on the list? – ChristianB Jan 08 '21 at 14:18
  • @ChristianB I think he wants to call `.collect{ }` from `getAllConversations` and map the list to another list while creating another flow. – Andrew Jan 08 '21 at 22:56

2 Answers2

1

I hope I understood your question correctly. If you want to collect getAllConversations() and then emit another flow from it while mapping it to another flow, you can simply call the function.collect { } and then emit it.

Since you did not provide much codebase, here is an example:

val myTestFlow: Flow<Int> = flowOf(1,2,3,4,5,6,7,8)

fun myNewFlow(): Flow<String> = flow  {
    myTestFlow.collect { myInt ->
        emit(myInt.toString())
    }
}
Andrew
  • 4,264
  • 1
  • 21
  • 65
  • What you do is a plain mapping. You do not need to collect and re-emit. You could just do `flow.map { it.toString() }`, but I do not know if that is what @rogalz wants. – ChristianB Jan 09 '21 at 10:49
1

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.

ChristianB
  • 2,452
  • 2
  • 10
  • 22