Skip to content
Source

ViewModel and init

I came across the first article in a series of best practices for working with ViewModel. Looks very similar in style to something from Google, which got me hooked, but thankfully it's not. In it, the author says that the init section in ViewModel is not recommended for state initialization. Yes, that's what's written - don't use init for initialization ✏️. Wait, what? I got interested.

They say it seems convenient at first glance, but it has downsides. Ok, let's go through them in order.

  • Tight Coupling with ViewModel Creation. That's the whole point of the init block, hello, if we initialize something in it, we want something to be initialized at startup, the connection is absolutely logical here.
  • Testing Challenges. They say it's hard to test VM because you'll write network requests at startup and it'll be flaky. Well, use mocks, making real requests in tests makes you your own evil Buratino. And it's not entirely clear what the problem is with testing the state after creating its instance.
  • Limited Flexibility. What if, they say, you want to load data not at startup, but after some event. Dude, first of all "what if" is a weak argument, second I'll just move the init block contents to a function and that's it, what's the problem?
  • Handling Configuration Changes. Here they say if you write something in the init block, configuration changes can lead to unexpected behavior or unnecessary data refetching and all that. Why would that happen? They themselves write that ViewModel doesn't get recreated on conf change. So init is called once, meaning the data comes to you once.
  • Resource Management and UI Responsiveness. They say everything we write in init works on the main thread, so it will cause lags and excessive resource consumption. Again yes, that's the point, you want to initialize something right away. You want some state to be assembled by default, some request to be triggered immediately and so on. You do something lightweight there so you don't have to wait for the view to even render, this will only affect the app's "performance" in a positive way, not to mention that you can render this initial state without flickering.

And what do they propose? They propose rewriting simple and clear code where in the init block in viewModelScope some loading is triggered to some reactive chains like flow{...}.stateIn() and stateFlow.asLiveData().switchMap{...} in properties. Which is either questionable, or just doesn't scale to more complex ViewModels, or isn't a universal solution, i.e. in each case you need to come up with a different solution. init is beautiful because you don't have to think, you write simple (almost) synchronous code in any scenario. Just don't forget to split it into functions to make it clear, that's all.

And I don't understand why all this at all, they're working around limitations they invented themselves. There's some food for thought, of course, but neither the arguments nor the solutions convince me at all. Am I missing something or is Medium hyping nonsense again? 🤔