- 
                Notifications
    
You must be signed in to change notification settings  - Fork 24
 
Flow: Terminal operators
        Devrath edited this page Dec 25, 2023 
        ·
        20 revisions
      
    Terminal Operators | 
|---|
First | 
Last | 
Single | 
ToList And ToSet | 
LaunchIn | 
- You can notice that we have used 
firstoperator. - Also, even the second edition has not happened, so emission stops after the 
first emission. - The flow is canceled once the 
first emissionis received. - If there are no elements then it would throw 
java.util.NoSuchElementException:To prevent this we can usefirstOrNullinstead of justfirst 
@HiltViewModel
class TerminalOperatorsVm @Inject constructor(
    @ApplicationContext private val context: Context,
) : ViewModel() {
    companion object {
        const val emissionDelay : Long = 100
    }
    private val terminalOperatorDemo = flow {
        delay(emissionDelay)
        println("Emitting first value")
        emit(1)
        delay(emissionDelay)
        println("Emitting second value")
        emit(2)
    }
    /** *********************** DEMO's *********************** **/
    /**
     * Terminal Operator: First
     */
    fun demoFirst() {
        viewModelScope.launch {
            val result = terminalOperatorDemo.first()
            println("Result:-> $result")
        }
    }
    /** *********************** DEMO's *********************** **/
}Emitting first value
Result:-> 1- Here also observe that all the emissions are done from the flow but only the last emission is received in flow
 
@HiltViewModel
class TerminalOperatorsVm @Inject constructor(
    @ApplicationContext private val context: Context,
) : ViewModel() {
    companion object {
        const val emissionDelay : Long = 100
    }
    private val terminalOperatorDemo = flow <Int>{
        delay(emissionDelay)
        println("Emitting first value")
        emit(1)
        delay(emissionDelay)
        println("Emitting second value")
        emit(2)
    }
    /** *********************** DEMO's *********************** **/
    fun demoLast() {
        viewModelScope.launch {
            val result = terminalOperatorDemo.lastOrNull()
            println("Result:-> $result")
        }
    }
    /** *********************** DEMO's *********************** **/
}Emitting first value
Emitting second value
Result:-> 2- If there is more than one element in the flow
- If we use 
singleit will returnIllegalArgumentException: More than one element - If we use 
singleOrNullit will return null 
 - If we use 
 - If there is just one element in the flow, It will return that element.
 
viewModelScope.launch {
    val result = terminalOperatorDemo.singleOrNull()
    println("Result:-> $result")
}- It provides us the ability to convert the flow into 
ListandSet. 
 fun toListAndToSet() {
        viewModelScope.launch {
            val resultList = terminalOperatorDemo.toList()
            val resultSet = terminalOperatorDemo.toSet()
            println("Result List:-> $resultList")
            println("Result Set:-> $resultSet")
        }
}Result List:-> [1, 2]
Result Set:-> [1, 2]- 
LaunchInis not a suspended function but a regular function. - So it will not suspend the coroutine which it is called.
 - Thus in the output observe that emissions are sent and receiving also happen before either of the co-routines to complete.
 
@HiltViewModel
class TerminalOperatorsVm @Inject constructor(
    @ApplicationContext private val context: Context,
) : ViewModel() {
    companion object {
        const val emissionDelay : Long = 100
    }
    private val terminalOperatorDemo = flow <Int>{
        delay(emissionDelay)
        println("Emitting first value")
        emit(1)
        delay(emissionDelay)
        println("Emitting second value")
        emit(2)
    }
   
    fun launchIn() {
        val scope = CoroutineScope(EmptyCoroutineContext)
        viewModelScope.launch {
            terminalOperatorDemo
                .onEach { println("Result Collect <1>:-> $it") }
                .launchIn(scope)
            terminalOperatorDemo
                .onEach { println("Result Collect <2>:-> $it") }
                .launchIn(scope)   
        }
    }
}Emitting first value
Result Collect <1>:-> 1
Emitting first value
Result Collect <2>:-> 1
Emitting second value
Emitting second value
Result Collect <1>:-> 2
Result Collect <2>:-> 2