# Flow .map and .collectLatest gets fired unstoppable

**URL:** <https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828>\
**Category:** Support\
**Created:** [June 30, 2024, 11:27am UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828 "2024-06-30T11:27:00Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![armantabibzadeh](https://avatars.discourse-cdn.com/v4/letter/a/f4b2a3/32.png) [@armantabibzadeh](https://discuss.kotlinlang.org/u/armantabibzadeh)\
**Post date:** [June 30, 2024, 11:27am UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/1 "2024-06-30T11:27:00Z")

</div>

Hello,  
I have an android application that has a structure like this (although it doesn’t make any difference, it being on android platform. I’m having trouble with flows):

```auto
data class MyChild(some stuff){...}

data class MySuper(val child: MyChild, val child2 : List<MyChild2>, val child3 : MyChild3, ...){...}

```

Now I have a flow like this:

```auto
private val _mainState = MutableFlow<MySuper>(MyDefaultSuper)

```

and in my ViewModels init I have:

```auto
fun myInit(child: MyChild){
    //myInit
    Log.d("someTag", "myInit")
    _mainState.update{it.copy(child = child)}
}
CoroutineScope(Dispatchers.IO).launch {
    var tempChild : Child? = null
  _mainState.map{it.child}.collectLatest{
      //1
      Log.d("someTag", "collect Child")
      if(tempChild != it){
          //2
          Log.d("someTag", "tempChild different")
          tempChild = it
      }
     //3
     _mainState.update{
     it.copy(child2 = emptyList())
     //4
     }
     _mainState.udpate{it.copy(cild2 = fetchFromNetwork())}
    
  }
}

```

Now when i clear out either the part `//3` or `//4` of the code, it works fine, but when I try do these parts, the log `//1` gets fired continuosly, although the part `//2` gets called once, so the `map` and `collectLatest` don’t work fine even though the `child` doesn’t changed.  
The `child` only changes in `myInit` function which is being called once, accoring to the Logs.  
Which part of my code is wrong?

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [June 30, 2024, 10:36pm UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/2 "2024-06-30T22:36:45Z")

</div>

What is your expected behavior? For each collect you again emit to the flow, which in turn results in another collect. It does this continuously.

---

<div class="post-metadata">

**Author:** ![armantabibzadeh](https://avatars.discourse-cdn.com/v4/letter/a/f4b2a3/32.png) [@armantabibzadeh](https://discuss.kotlinlang.org/u/armantabibzadeh)\
**Post date:** [July 1, 2024, 6:19am UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/3 "2024-07-01T06:19:04Z")

</div>

Shouldn’t the `map` or `collectLatest` filter out the emits that don’t change the `child` field?

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [July 1, 2024, 12:47pm UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/4 "2024-07-01T12:47:56Z")

</div>

You may be interested to [Flow.distinctUntilChanged  
 ](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/distinct-until-changed.html)

---

<div class="post-metadata">

**Author:** ![clovisai](https://avatars.discourse-cdn.com/v4/letter/c/a9adbd/32.png) [@clovisai](https://discuss.kotlinlang.org/u/clovisai)\
**Post date:** [July 2, 2024, 9:58am UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/5 "2024-07-02T09:58:00Z")

</div>

Using a `CoroutineScope` anonymously (without storing a reference to it) is dangerous, because there’s a chance your entire coroutine gets GC’d while it’s suspended. Either keep a reference to the job or the scope itself.

---

<div class="post-metadata">

**Author:** ![armantabibzadeh](https://avatars.discourse-cdn.com/v4/letter/a/f4b2a3/32.png) [@armantabibzadeh](https://discuss.kotlinlang.org/u/armantabibzadeh)\
**Post date:** [July 2, 2024, 10:10am UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/6 "2024-07-02T10:10:54Z")

</div>

As I see now, I didn’t provide the information needed in a good way. The line  
`CoroutineScope(Dispatchers.IO).launch...` happens in the init of ViewModel

---

<div class="post-metadata">

**Author:** ![Varia](https://avatars.discourse-cdn.com/v4/letter/v/b9e5f3/32.png) [@Varia](https://discuss.kotlinlang.org/u/Varia)\
**Post date:** [July 2, 2024, 11:33am UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/7 "2024-07-02T11:33:59Z")

</div>

`MutableStateFlow` filters out updates that do not change the parent object, however, since you do change `child2`, this will not block it from emitting. `map` does not do any filtering of its own, so the downstream flow will still emit whenever the the parent flow does. As mentioned earlier, you can use `distinctUntilChanged` on the flow produced by `map` to filter out updates that leave `child` unchanged

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [July 2, 2024, 3:49pm UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/8 "2024-07-02T15:49:22Z")

</div>

> [@clovisai](#):
>
> Using a `CoroutineScope` anonymously (without storing a reference to it) is dangerous, because there’s a chance your entire coroutine gets GC’d while it’s suspended

Are you sure about this? If we suspend, then someone has to keep a reference to a continuation, because otherwise the coroutine could never resume. I don’t see how GCing the scope would GC the coroutine/continuation as well.

---

<div class="post-metadata">

**Author:** ![ebrowne72](https://avatars.discourse-cdn.com/v4/letter/e/85f322/32.png) [@ebrowne72](https://discuss.kotlinlang.org/u/ebrowne72)\
**Post date:** [July 2, 2024, 4:57pm UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/9 "2024-07-02T16:57:37Z")

</div>

If you’re using a ViewModel, then the proper way to launch a coroutine is

```auto
viewModelScope.launch(Dispatchers.IO) { ... }

```

That way the coroutine will be cancelled when the ViewModel goes away.

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [July 3, 2024, 5:25am UTC](https://discuss.kotlinlang.org/t/flow-map-and-collectlatest-gets-fired-unstoppable/28828/10 "2024-07-03T05:25:05Z")

</div>

Just gonna re-iterate what’s already been said; you’re emitting an item to the flow inside the collector. So every time you collect an item, you send a new item. Then you collect the new item, and send another new item. So it’s gonna collect → send → collect → send forever and ever and ever.
