# How to change coroutine scope?

**URL:** https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495
**Category:** Android
**Created:** [December 18, 2019, 12:05pm UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495 "2019-12-18T12:05:32Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)
#### Post date: [December 18, 2019, 12:05pm UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/1 "2019-12-18T12:05:32Z")

</div>

Say, you have to make as suspending HTTP call in your `ViewModel` and based on that response execute an `action: (Boolean)->Unit`.  
Now, `action()` need to be executed in the `Activity`/`Fragment` `lifecicleScope` so i would do something like:

```kotlin
// we are into the ViewModel
fun makeCall(
    lifecycleScope: AndroidLifecycleScope, 
    action: (Boolean) -> Unit
) = viewModelScope.launch {
  try {
    val result = httpClinet.get<MyClass>(myUrl)
    lifecycleScope.launch { action(true) }
  } catch (e: Throwable) {
    lifecycleScope.launch { action(false) }
  }
}

```

The problem here is that i need to catch the error inside `makeCall()` since the error does not get propagated.  
Also, is this the correct way to handle this usecase? I am pretty sure I am missing something.

Should I post the error as well as a `MutableLiveData<Throwable>` and observe it?

---

<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: [December 18, 2019, 11:48pm UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/2 "2019-12-18T23:48:21Z")

</div>

First, why does `action()` need to run in a scope? It’s not a `suspend` function.

Second, passing a callback doesn’t seem very coroutine-y.

Third, this doesn’t seem very MVVM-y. The `Activity/Fragment` should observe some property in the view model to know when the call completes. The data in the property should be relevant to what the view needs to display. The view doesn’t care what exception was thrown, just that there was a failure.

Maybe the property is a sealed class, with one subclass for “processing” (view displays a progress spinner), one for success which contains the result, and one for failure which contains an error message to display to the user.

---

<div class="post-metadata">

### Author: ![mtimmerm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mtimmerm/32/7160_2.png) [@mtimmerm](https://discuss.kotlinlang.org/u/mtimmerm)
#### Post date: [December 19, 2019, 2:18am UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/3 "2019-12-19T02:18:17Z")

</div>

How about:

```
fun makeCall(
    lifecycleScope: AndroidLifecycleScope, 
    action: (Boolean) -> Unit
) = lifecycleScope.launch(start = CoroutineStart.UNDISPATHCED) {
  try {
    withContext(viewModelScope.coroutineContext) {
        httpClinet.get<MyClass>(myUrl)
    }
    action(true)
  } catch (e: Throwable) {
    action(false)
  }
}

```

This will call `withContext` in the calling thread, which will schedule `httpClient` in the view model context, and resume from `withContext` in the life cycle context.

---

<div class="post-metadata">

### Author: ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)
#### Post date: [December 19, 2019, 8:41am UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/4 "2019-12-19T08:41:38Z")

</div>

Yeah I forgot to add the `suspend` modifier to `action`.  
Indeed I am a little ashamed of this solution.

In my app, what I am trying to achieve is to wait for the login call, then if it ended without error, let the activity know it. The possible errors are sealed classes. I suppose I should catch the error and post either a Boolean or the error.

The reason behind why I was using the lifecycleScope was to avoid to call action if the owner was destroyed. Indeed observing the error as `MutableLiveData<AuthException>` is more elegant and Android friendly.

But still, what’s the idiomatic way of changing scope?

---

<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: [December 19, 2019, 9:30pm UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/5 "2019-12-19T21:30:40Z")

</div>

In the world of structured concurrency, launching a coroutine in another scope is sort of like `goto`, which is evil 😉. So I don’t think you should do it.

Conceptually, the only thing that should launch coroutines on a scope is the thing that owns the scope. The Activity has a scope, so only the Activity should launch on the scope.

---

<div class="post-metadata">

### Author: ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)
#### Post date: [December 19, 2019, 9:35pm UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/6 "2019-12-19T21:35:00Z")

</div>

So I am not approaching the problem correctly?

---

<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: [December 19, 2019, 9:37pm UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/7 "2019-12-19T21:37:57Z")

</div>

The real question is, “What problem are you trying to solve?” We’ve already got a solution for your original problem that doesn’t involve changing scope. So what’s a problem whose solution _might_ involve changing scope?

---

<div class="post-metadata">

### Author: ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)
#### Post date: [December 19, 2019, 10:02pm UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/8 "2019-12-19T22:02:22Z")

</div>

Good point

---

<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: [December 19, 2019, 10:03pm UTC](https://discuss.kotlinlang.org/t/how-to-change-coroutine-scope/15495/9 "2019-12-19T22:03:27Z")

</div>

@mtimmerm I think that code will do one of two things:

1. The `withContext` will crash because you are mixing contexts from two different scopes.
2. It will switch execution to the dispatcher used by the `viewModelScope`, but it’s still running in the `lifecycleScope`, so it will be cancelled if the `lifecycleScope` is cancelled, which isn’t what we want.
