# Using coroutines scoped to ViewModel for IO

**URL:** <https://discuss.kotlinlang.org/t/using-coroutines-scoped-to-viewmodel-for-io/10327>\
**Category:** Android\
**Created:** [November 14, 2018, 11:03pm UTC](https://discuss.kotlinlang.org/t/using-coroutines-scoped-to-viewmodel-for-io/10327 "2018-11-14T23:03:59Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![andreartus](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/andreartus/32/5754_2.png) [@andreartus](https://discuss.kotlinlang.org/u/andreartus)\
**Post date:** [November 14, 2018, 11:03pm UTC](https://discuss.kotlinlang.org/t/using-coroutines-scoped-to-viewmodel-for-io/10327/1 "2018-11-14T23:03:59Z")

</div>

So far as I can make out the following is a very common pattern for enabling coroutines in Android ViewModels.

```
class CoroutineScopedViewModel : ViewModel(), CoroutineScope {
    private val _job = Job()
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + _job

    override fun onCleared() {
        super.onCleared()
        _job.cancel()
    }

    fun thisIsCalledFromDataBoundView() = launch {
        /* do some UI */
        withContext(Dispatchers.IO) {
            try {
                /* do some IO */
            } catch (error: IOException) {
                /* do some exception handling */
            }
        }
    }
}

```

Before I go about refactoring my project from the experimental (pre-1.0.0) version, I need to just have something clarified:

If the activity or fragment attached to the viewmodel is closed before the withContext([Dispatchers.IO](http://Dispatchers.IO)) block is completed will that child job be canceled before completing? I.e. can this model be used for inserting data into my DB, or could some strange timing issue arise where the user hits back or otherwise causes the ViewModel owner to close that ends up losing the data?

To be clear I currently use `GlobalScope.launch(Dispatchers.IO) ` (quickest conversion from 1.2.7x to 1.3.x) to write user entries into the SQLite DB (that I later sync with a server in the background), I just don;t want to inadvertently introduce a timing bug because I misunderstood something and converted to the model shown above.

---

<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:** [November 23, 2018, 6:59pm UTC](https://discuss.kotlinlang.org/t/using-coroutines-scoped-to-viewmodel-for-io/10327/2 "2018-11-23T18:59:37Z")

</div>

You’re correct, the `withContext` will be cancelled if the ViewModel goes away. You could take advantage of the fact that cancellation is cooperative, but that seems ugly to me.

I think if you want the DB write to succeed then it needs to be done in a different scope. `GlobalScope` is probably fine. So instead of `withContext`, use `GlobablScope.launch(Dispatchers.IO)`. Actually I’d move that into a separate class, like some kind of repository class.

---

<div class="post-metadata">

**Author:** ![andreartus](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/andreartus/32/5754_2.png) [@andreartus](https://discuss.kotlinlang.org/u/andreartus)\
**Post date:** [November 23, 2018, 7:54pm UTC](https://discuss.kotlinlang.org/t/using-coroutines-scoped-to-viewmodel-for-io/10327/3 "2018-11-23T19:54:23Z")

</div>

> [@ebrowne72](#):
>
> use `GlobablScope.launch(Dispatchers.IO)`

That’s how I have it currently. I just see so many examples to the contrary (using a form similar to what is shown in my initial post) that it had me wondering if I’m doing something wrong.

---

<div class="post-metadata">

**Author:** ![reem.halamish](https://avatars.discourse-cdn.com/v4/letter/r/6f9a4e/32.png) [@reem.halamish](https://discuss.kotlinlang.org/u/reem.halamish)\
**Post date:** [January 21, 2019, 4:20pm UTC](https://discuss.kotlinlang.org/t/using-coroutines-scoped-to-viewmodel-for-io/10327/4 "2019-01-21T16:20:15Z")

</div>

Jumping a little bit late to the party, but here are my 2 cents:  
In our code all of the view models inherit from a base view model who implements CoroutineScope  
Some of the view models are only there to get a nice proccessed data to the UI, smoe are there to actualy manipulate data and do actual work.

In a typical view model class,  
whenever there is **some data to be retrieved** , we would use `this.launch { ... }` to get it  
whenever there is **some work to be done** (your example with DB insertions is good here) we use `GlobalScope.launch { ... }`
