Is this the correct way to attach a new `Job` to t...
# coroutines
r
Is this the correct way to attach a new
Job
to the parent context?
Copy code
val connectionJob = Job(viewModelScope.coroutineContext.job)
s
Depends what you're trying to achieve. Creating a custom
Job
isn't something you should need to do much, and it's very easy to get wrong. What's stopping you from just making a job with
launch
?
b
Yes, but it can only make sense in a very specific cases. The more convenient is to just
val connectionJob = viewModelScope.launch { }
👍 1
r
So in case I need two
launch
, nest them inside?
s
Sure, why not 👍
r
So tie the knot like this?
Copy code
lateinit var connectionJob: Job
                        connectionJob = viewModelScope.launch {
                            launch {
                                connection.state.collect {
                                    bluetoothConnectionState.value = it
                                    when (it?.state) {
                                        GattConnectionState.STATE_DISCONNECTED -> {
                                            connectionJob.cancel()
                                        }

                                        else -> {}
                                    }
                                }
                            }
                            launch {
                                connection.networkState.collect {
                                    networkingStateFlow.value = it
                                }
                            }
                        }
Oops, the inner
launch
were wrong
👍 1
s
Inside the outer job, you need to leave out the
viewModelScope
part. The
launch
block creates its own scope, and you want your inner jobs to be children of that scope, instead of the outer scope.
r
More on the
lateinit var
Sorry, slack ain't very good at properly indenting code, and I'm not sure how to left-align it in the editor window 😕
d
Typically it's • Highlight the code you want to indent, • Press Shift+Tab several times.
r
Nope, doesn't work, as the
connectionJob
isn't properly wired in, gotta go with the
Job
d
`connectionJob`'s parent is certainly `viewModelScope`'s job when you create it using
viewModelScope.launch {}
.
r
connectionJob
will be
null
inside though, so that's not gonna work out too well
d
Do you only want to use
connectionJob
inside the
launch
?
r
Yeah
d
Then you don't need it at all.
Copy code
viewModelScope.launch {
    val connectionScope = this
    launch {
        connection.state.collect {
            bluetoothConnectionState.value = it
            when (it?.state) {
                GattConnectionState.STATE_DISCONNECTED -> {
                    connectionScope.cancel()
                }

                else -> {}
            }
        }
    }
    launch {
        connection.networkState.collect {
            networkingStateFlow.value = it
        }
    }
}
r
Even better
Time to rework my code to remove a bunch of
Job()
usages ^^