Injecting ViewModels with Dagger 2 on Android (Map Multibindings)
ฝัง
- เผยแพร่เมื่อ 10 ก.พ. 2025
- By default you can't inject ViewModels using Dagger. But there is a pretty well-known work-around using map multibindings.
In this video I show you how to inject ViewModels and perform constructor injection on ViewModels with Dagger using map multibindings.
➤ Watch the dagger course free:
↻ codingwithmitc...
➤ Code for this video:
↻ github.com/mit...
This is the only vdo on the youtube which has the courage to explain this concept. Thank you Mitch!
When I am confused about dagger, I am very thankful that I saw this course, and I am grateful to Mitch.
read the article before, was a lot of useful for this video thanks!!
Nice. The article is very good.
@Etelred Etelred www.techyourchance.com/dependency-injection-viewmodel-with-dagger-2/
If some one is facing the issue on kotlin
"error: [Dagger/MissingBinding] java.util.Map
Thanks, I ran into this problem and luckily I see your comment
thanks man! you are awesome!
Thanks!!
Thanks
thanks for solution !
Stay tuned for Google's new Dagger-Hilt library which is expected to improve injectionof ViewModels and other dynamic parameter user cases.
See:
• proandroiddev.com/hilt-first-impressions-31f55cf57b3f
• proandroiddev.com/exploring-dagger-hilt-and-whats-main-differences-with-dagger-android-c8c54cd92f18
thanks for saving my time .Read the article before also helpful. :)
Hi mitch, I am getting the log "Viewmodel working fine" 2 times in the logcat as my constructor of AuthViewModel calling 2 times. Is it fine or some bug?
I think this is a bug
Very helpful and thank you for saving me, and making such tough things hands on
9:08 but why i can omit constructor injection when using provides?
Hi Mitch,
Nice explanation, I have one question for you.
We are using ViewModelProvider or ViewModelProviderFactory to get ViewModel. It's fine.
But I'm trying to get ViewModel object within our view class without using ViewModelProvider or ViewModelProviderFactory, it's working as well.
What's the issue with that?
//////Module Class/////
@MainScope
@Provides
fun provideWeatherViewModel(mainApi: WeatherRepoImpl): WeatherViewModel {
return WeatherViewModel(mainApi)
}
/////Fragment Class//////
@Inject
lateinit var weatherViewModel: WeatherViewModel
........ And it's working perfectly, then why all these multi binding?
Did you find any answer?
Hi Mitch,I need your help.
While doing the same code in Kotlin I am getting an error as below:
[Dagger/MissingBinding] java.util.Map
Thank you so much. I have a question that how we pass SaveSatateHandle for this ViewModel ?
Okay Mitch
, Sure!
Is it really good practice to keep all viewmodels alive in appcomponents scope?
Why not scope a seperate viewmode factory to a subcomponent and destroy subcomponent when viewmodel oncleared() is called?
That's what she said!
I was writing this hahaahahhaha
I don't know how to thank you! I was stuck with an error that couldn't create the instances of my VIewModels. I did everything but add that ViewModelKey. That was the...key to my problems haha.
As of video #13 I'm still asking myself why all this for? Programmed on Android like already for 10 years and still not seeing the point. Let's see if it this changes later on.
Hi Mitch, first of all, great video. I follow and understand almost all the steps. The one couldn't get is, on the ViewModelFactoryModule who is instantiating the ViewModelProviderFactory for the bindFactory method to use?
The code generator. Open the generated code directories and take a look.
And how can i provide Context in ViewModel, using your method and @Component.Factory?
Hey, Mitch
I am new to Dagger and will agree that it is probably the hardest thing in Android I have tried to learn yet. I am following your video word for word and come up with this Dagger error:
"error: cannot find symbol import com.curiousapps.dagger2practice.di.DaggerAppComponent;
^
symbol: class DaggerAppComponent
and have traced it specifically to this line in the AuthActivity
@Inject //This Inject command breaks BaseApplication. DaggerAppComponent becomes
// unavailable to the application in the generated code. I don't yet know why.
ViewModelProviderFactory providerFactory;
And more specifically when i add the @Inject, the project will not build with the above error. If I comment it out, the project builds .
Any help here is appreciated.
i also found the same error but managed to fix it
i was injecting in viewmodels constructor, dependecies from modules without creating a viewmodelproviderfactory
when i removed the dependecies from the constructor and rebuild it accepted the build
Hey Mitch,
Here is what I tried.
1. I created a ViewModel class which extends ViewModel.
2. The Constructor had no arguments and body except a log saying ViewModel is created with @Inject annotation.
3. I added a provideViewModel() method inside AppModule and returned "new ViewModel()"
4. I declared the ViewModel in the activity and added inject annotation.
Voila! I got the ViewModel injected. I tried the same for AndroidViewModel too which has an application argument on the constructor.
Here, I am curious to know how the ViewModel got injected. I didn't follow any of the complex steps you suggested in the video but how did it work? :-| Request you to please answer and clarify.
There's gotta be something wrong with doing it that way. Or the google samples would do it.
Try doing constructor injection into that viewmodel. Also try field injection.
I was so bad at it :-| I created object of ViewModel just like any other class and hence it worked. But this will not hold the functionality of ViewModel :-!
How to setup ViewModel workaround in Kotlin coz every time I am getting this error: [Dagger/MissingBinding] java.util.Map
This project is in kotlin. You can compare: github.com/mitchtabian/Open-API-Android-App
@@codingwithmitch Thanks Mitch, for your project but I follow the same workaround but still getting this error.
@@santanumukherjee374 adds @JvmSuppressWildcards before Provider in ViewModelProviderFactory constructor
Does anyone facing same problem like me? DaggerAppComponent not found
error: cannot find symbol class DaggerAppComponent (while compiling project, unable to run the app)
It happened after @Inject toward ViewModelProviderFactory in the AuthActivity.java
I have rewatch this video for 2 times to make sure i dint missed out every single steps yet no luck, I even cloned down the mitch@github version branch of github.com/mitchtabian/Dagger-Examples/tree/map-multibindings-and-viewmodels and it came up another strange error about
error: no suitable method found for of(AuthActivity,ViewModelProviderFactory)
method ViewModelProviders.of(Fragment,Factory) is not applicable
(argument mismatch; AuthActivity cannot be converted to Fragment)
method ViewModelProviders.of(FragmentActivity,Factory) is not applicable
(argument mismatch; AuthActivity cannot be converted to FragmentActivity)
any help is appreciated
@@elliotching1142 that is a generic error you get from dagger when you've done aomsething wrong. (yes I know, not helpful). But here's what you can do:
1) return null from applicationInjector in BaseApplication
2) run it again
That will give you an error message that's more meaningful
@@codingwithmitch Yes, it gave me more meaningful error message but sorry I still failed to solve it.
error: [Dagger/MissingBinding] Map
@@elliotching1142 dunno, you did something wrong with the multibinding. Check my code on git
viewmodelproviders is deprecated. So how to get viewmodel in this case. Can you help in this?
viewModel = ViewModelProvider(lifecycleOwner,factory)[YourViewModelClass::class] -> Kotlin
viewModel = new ViewModelProvider(getViewModelStore(),providersFactory).get(AuthViewModel.class); -Java
@@MusfickJamil thank you!
Very much helpful to me. Thanks
thank you so much, Mitch, your videos are so helpful. I am from Iran and Unfortunately, I can't watch your unfree courses because of sanctions I can't pay.
Hi Mitch should have explained 'constructor injection' a bit initially..
One question.... Instead of creating a seperate Module to provide 'ViewModelFactory' , Why didn't you provide 'ViewModelFactory' from 'AppModule' ???
much love
ViewModelProviders.of() is depricated in androidx.lifecycle:lifecycle-extensions:2.2.0-alpha03. Can you please replace ViewModelProviders.of() in your code.
No but you can
I found this solution
viewModel = new ViewModelProvider(
getViewModelStore(),
providerFactory
)
.get(AuthViewModel.class);
Why don't we extend AndroidViewModel which can take parameter through constructor? just asking
AndroidViewModel is the same other than the application context. Which we don't need because dagger supplies it
Thanx mate
Hi, I was wondering that you said that this ViewModelProviderFactory is a Singleton but we didn't Scoped it with @Singleton.
That viewmodelfactorymodule is the class that is used for factory injection has declared in the app level singleton...
sir ViewModelProviders.of id deprecated how to resolve it
ViewModelProvider(this).get(YourViewModel::class.java)
Hey every one When google come with solution? thanks
its very helpfull , thanks
Sir, please inform audience that the issue discussed in video is resolved by google.
if it is fixed then shall we skip this multibinding part in our code?
I appreciate your effort , I think Kotlin solve this problem by Koin , I hope to see more videos about Kotlin Topics
This is hard!!!! I used kodein dependency injection with kotlin. The factory class using Kodein is pretty sample but I get errors and as always came back to this video to see if it will help but this dependency injection is pretty hard.
Dagger is definitely the hardest thing I've learned on android. But once you get it, it's very simple. Everything is the same for every project
isn't this issue fixed yet?
in Kotlin ViewModelProvider(this, providerFactory).get(AuthViewModel::class.java)
you mean and that's it? instead of tens of classes?
thanks you help a lot
useful video thx!!!
Multi binding 13:33
Mitch you have great discourse I like them all but this particular section is very very poorly organized. Dagger multibindings are not complex at all but your order of arranging things is complicating this matter. Why don't you put a 5 minute multibindings hands on video beforehand?
Dunno, I just decided to do it this way
Hi again Mitch, I'm the "Firebase guy" :) I really appreciate the efforts you constantly make to create high quality content but in this tutorial I really don't understand a thing. You are creating a Dagger2 tutorial which has as a primary purpose dependency injection but you are still creating objects in the activity. Why are you injecting the ViewModelProviderFactory and not the ViewModel it self? When using Dagger2, the main purpose is to eliminate all objects creation from our activities/fragments. You can take a look here: github.com/alexmamo/FirebaseApp-Clean-Architecture-MVVM/blob/master/app/src/main/java/ro/alexmamo/firebaseapp/auth/AuthActivity.java See, you can inject the ViewModel directly. Hope you understand what I mean.
You cant inject a viewmodel directly. It doesn't work properly. This is a known issue.
@@codingwithmitch Sorry Mitch but I totally disagree with you. You can inject a ViewModel object directly in your activity. I'm using that all the time in my projects. One example is the repo above. Even in your tutorial, you can remove the creation of the ViewModel object in the activity and inject it directly. Check this out i.ibb.co/Yckv2YG/View-Model.jpg If you have time, you can give it a try ;)
@@AlexMamo I'll take a look. If that works then something was changed because it didn't used to.
Hello Alex, how do you declare whether the ViewModel is attached to the activity or the fragment in this case? like the alternative of using this line in the fragment ViewModelProviders.of(this ~ fragment / getActivity()) ...
@@hadifromlebanon3812 Good question. When you inject a ViewModel directly in your activity/fragment it means that you inject an object that is already created. When Dagger creates the ViewModel object, a Context object is also required. So in the say same way, you should also tell Dagger to create an Context object that should be used in the creation of ViewModel object ;)
ViewModelProviders is deprecated
For some reason I couldn't get this to work :(
Never mind. I forgot to put @Inject annotation over my view model constructor.
😇👍👍
MapKey structure
@Documented
@Target(iElementType.MEM001)
@Retention(Retentionfolicy.RUNTIME)
@MapKey
public @interface ViewModelKey Class
@MustBeDocumented
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass)
ViewModelProviders is deprecated now!
While reading the article you recommended, I came across this article www.techyourchance.com/dagger-android-dead/ from the same guy.
Need your comment on this as you are using dagger.android in this course.
Oooh... my brain.....
😂😂
you're creating this this class you're
creating a key map it Maps the view
model to the key create this view model
factory dependency create the view model
dependency no it's no