https://kotlinlang.org logo
d

dave08

02/03/2020, 4:13 PM
I guess the easiest way is having a
lateinit var
that's initialized when the viewmodel is injected in the Fragment... but that's a bit of a brittle way to do things?
s

satyan

02/03/2020, 4:14 PM
Register and unregister the Broadcast receiver from the fragment and post received values to the view model ?
d

dave08

02/03/2020, 4:16 PM
You mean providing a
MutableLiveData
from the
ViewModel
that the view can post to? It wouldn't have been a bad idea... but in my case, I need to combine that
Flow
with one I'm getting from a repository...
s

satyan

02/03/2020, 4:21 PM
Maybe you could expose a broadcast receiver created in your VM that you would register/unregister in your fragment ? You might be able to get away without leaking your context 🤔. But I’d rather handle Broadcast receiver in the view part and treat it as if it was view inputs
d

dave08

02/03/2020, 4:24 PM
I'm really trying to get rid of
Context
from my VM to make unit tests... having a Flow exposed instead of
BroadcastReceiver
code makes it easy to mock... I guess for now a
lateinit var
is the way to go... just wondering what everybody else does in this case. Your idea for
MutableLiveData
might also come in handy in other situations... thanks!
s

satyan

02/03/2020, 4:30 PM
I wouldn’t use a
MutableLiveData
. I’m not sure it is a good practice to push from the view to the ViewModel using a MutableLiveData. Just expose a method in your view model 🤷
🙈 1
d

dave08

02/03/2020, 4:37 PM
Yeah,
LiveData
is really to manage View lifecycles...
h

Hakob Astvacatryan

02/03/2020, 4:58 PM
I would do it with wrapper class implementing some interface and injecting it in VM
d

dave08

02/03/2020, 5:40 PM
Still with a
lateinit var
though... since I need to register that
BroadcastReceiver
...?
Just instead of having it on the
ViewModel
, I'd need to inject the class implementing the interface...
h

Hakob Astvacatryan

02/03/2020, 5:42 PM
you can implement ViewModelFactory and pass that interface with constructor
i mean you can have
val
d

dave08

02/03/2020, 5:44 PM
Yeah but the actual
var
containing the
Flow
needs to be initialized in
onCreateView()
of the Fragment so that the viewmodel can listen to it...
So either the injection must be done after creating the wrapper class in
onCreateView()
or just having a
lateinit var
just does the same?
h

Hakob Astvacatryan

02/03/2020, 5:46 PM
Why you want to do it in
onCreateView
?
d

dave08

02/03/2020, 5:49 PM
Because I need a
Context
to register that receiver with the lifecycle of the
Fragment
...
h

Hakob Astvacatryan

02/03/2020, 5:51 PM
Your wrapper interface implementation can have context provided by constructor and you can use it to register broadcastreceiver
and the context can be even applicationContext
d

dave08

02/03/2020, 5:57 PM
Yeah, I see what you mean now... I guess it could be cleaner in a sense, I just wonder if its worth the overhead unless there's more than one field... thanks!
h

Hakob Astvacatryan

02/03/2020, 5:59 PM
if you want to not have platform specific code in
ViewModel
for testing purposes it worth 🙂
d

dave08

02/03/2020, 6:07 PM
So for that I have a Flow... see the code I posted before (fromBroadcast) 😉
For testing I just use flowOf in the lateinit var...
a

Anastasia Finogenova

02/03/2020, 10:03 PM
You can extend AndoroidViewModel instead of ViewModel and inject application for the context (it accepts application as a param) and then mock it, Androidx testing core library provides now support for mocking Andoroid components
5 Views