Home > Enterprise >  Flow.take(ITEM_COUNT) returning all the elements rather then specified amount of elements
Flow.take(ITEM_COUNT) returning all the elements rather then specified amount of elements

Time:12-18

I've a method X that's getting data from the server via pub sub. This method returns a flow. I've another method that subscribes to the flow by method X but only wants to take the first 3 values max from the flow if the data is distinct compared to previous data. I've written the following code

fun subscribeToData() : Flow<List<MyData>> {
    ....
    //incoming data
    emit(list)
}

fun getUptoFirst3Items() {
   subscribeToData()
   .take(ITEM_COUNT) // ITEM_COUNT is 3
   .distinctUntilChange() //only proceed if the data is different from the previous top 3 items
   .mapIndex {
     //do transformation
   }
   .collect { transformedListOf3Elements ->
    
   }

}

Problem:

In collect{} I'm not getting 3 elements but rather I'm getting all the data that's coming in the flow.

I'm not sure what's wrong here? Can someone help me?

CodePudding user response:

You have a Flow<List<MyData>> here, which means every element of this flow is itself a list.

The take operator is applied on the flow, so you will take the 3 first lists of the flow. Each individual list is not limited, unless you use take on the list itself.

So the name transformedListOf3Elements is incorrect, because the list is of an unknown number of elements, unless you filter it somehow in the map.

CodePudding user response:

@Joffrey answer already explained why you get the whole list retuned and suggested you use take on the list itself.

If you want to take just the first ITEM_COUNT elements from every list that is emitted/observed, then you have to map the result and only take 3 items from the list each time, instead of taking 3 items from the flow.

fun getUptoFirst3Items() {
   subscribeToData()
   .map {
     // in Kotlin stdlib Iterable<T> has an extension method take(n: Int)
     // that will return a List<T> containing the first n element from the iterable
     it.take(ITEM_COUNT)
     // alternatively you can also use subList, but the semantics are not the same,
     // so check the subList documentation, before using it
     it.subList(0, ITEM_COUNT)
   }
   .distinctUntilChange() //only proceed if the data is different from the previous top 3 items
   .mapIndex {
     //do transformation
   }
   .collect { transformedListOf3Elements ->
    
   }

}
  • Related