0

I'm exploring the ViewModel from the Android Jetpack suite and I am not sure which of these two approaches is regarded as the most "right" to have some data that need Context to be obtained (for example reading a local JSON file in the /asset folder) inside the ViewModel

  • Have an external context-aware entity (Fragment/Activity/Application/Centralised function) inject the data to the ViewModel in the constructor (here done with the Koin library from the Application class)
      class MyApp : Application() {

         private val someListOfData by lazy {
            // read some local json using the Context
          }

         override fun onCreate() {
            super.onCreate()
            startKoin {
               androidContext(this@MyApp)
               modules(module {
                  viewModel { MyViewModel(someListOfData) }
               })
            }
         }
      }

      class MyFragment : Fragment() {
         // ViewModel injected with Koin
         val viewModel: MyViewModel by viewModel()
    
         // Fragment body
      }

      class MyViewModel(private val listOfData: List<String>) : ViewModel() {
    
         // ViewModel body with data passed in the constructor
      }
  • Use a AndroidViewModel instead of a ViewModel and leverage its knowledge of the hosting Application to retrieve the data from inside the ViewModel
      class MyApp : Application() {

         override fun onCreate() {
            super.onCreate()
            startKoin {
               androidContext(this@MyApp)
               modules(module {
                  viewModel { MyViewModel(this@MyApp) }
               })
            }
         }
      }

      class MyFragment : Fragment() {
         // ViewModel injected with Koin
         val viewModel: MyViewModel by viewModel()

         // Fragment body
      }

      class MyViewModel(app: Application) : AndroidViewModel(app) {

         private val someListOfData by lazy {
            // use Context to obtain the data
         }
      }
kioli
  • 635
  • 1
  • 10
  • 26
  • why do you need context in a VM ? `for example reading a local JSON file in the /asset folder` why do this in the VM ? either way, there's barely a difference in these 2 options – a_local_nobody May 26 '21 at 10:39
  • That is actually my question, if there are guidelines of clean coding/ testability/ separation of concerns etc that should be applied to the situation – kioli May 26 '21 at 11:01
  • generally speaking, i believe using an android VM is probably frowned upon, because usually people use it without needing it and then testing isn't efficient, due to always needing context (also, do you _really_ need application context ?) . but all of this, even my own comments, really just are based on opinion, so don't really think you'll find an answer here. might be worth asking on software engineering, perhaps – a_local_nobody May 26 '21 at 11:31
  • i guess my main point would be that, if you're using something like koin to manage dependencies, why wouldn't you use it to help make VM's as well. – a_local_nobody May 26 '21 at 11:34
  • Should I read your last sentence "if you're using something like koin to manage dependencies, why wouldn't you use it to help make VM's as well" as a "Given that you are using Koin I think it's preferable to use the first option with Koin injection"? :) – kioli May 26 '21 at 11:59
  • you are free to interpret what i say in any way you want, as long as it's positive :) again, personally i don't really ever see the need to use an Android VM, you can get away with passing in context to the required method or just use a normal VM with context passed to the constructor. [worth reading](https://stackoverflow.com/questions/44148966/androidviewmodel-vs-viewmodel) – a_local_nobody May 26 '21 at 13:21

0 Answers0