CodeNewbie Community 🌱

Cover image for What is by viewModels{} in Android
Tristan
Tristan

Posted on

What is by viewModels{} in Android

Introduction

  • This series is not going to be in any particular order, so feel free to read whatever blog post you want. Anytime I find something that I think could use a blog post, I will write one and put it here

Quick summary of entire blog post

  • So with by viewModels {} we are first creating a delegate property through the by keyword. Then we use the extension function viewModels to delegate a new getter method to our delegate property. Finally The {} allows to define a lambda expression to return the value that will be stored in our property.

What we are going to talk about

  • So ultimately, the goal of this post is to better understand the code below:
private val calfViewModel: CalfViewModel by viewModels {

        CalfViewModelFactory((activity?.application as 
        CalfApplication).repository)
}
Enter fullscreen mode Exit fullscreen mode
  • More specifically I am going to try and explain the by viewModels {} section of the code. I am the type of person that works backwards, I get the code working first and then try to understand it. Hopefully, by the end of this post both you and I will have a better understanding of what is going on in our code base.

The by keyword.

  • If we read the documentation of viewModels,Here, it states Returns a property delegate to access ViewModel by default scoped to this Fragment:. Awesome!! Except what exactly is a property delegate ? Well, we know that anything defined with either var/val is a property and according to Kotlin's documentation, HERE anything after by keyword is a delegate. So the combination of a property being defined and the by keyword creates a delegate property. The documentation provides a more formal definition of the syntax required to create a delegate property, val/var <property name>: <Type> by <expression>. A property automatically gets it's own getter and or setter, but when we use the by, we are stating that these accessor methods(getters and setters) are provided elsewhere, they are being delegated. We are delegating that job to an explicit function, in our case it is viewModels. I should also point out that we are using val and not var, try changing the two in your code and notice the error you get.

What is viewModels{}

  • So we can tell from the documentation, HERE, that viewModels falls under the extension function category. So what is an extension function?

Extension function

  • One of the main themes of Kotlin is smooth integration with existing code. Even pure Kotlin projects are built on top of Java libraries (Android being one of them). Extension functions come into play because they allow us to use all the niceties of Kotlin without having to rewrite them. Conceptually an extension function is a function that can be called as a member of a class but is defined outside of it.
  • So by that we know that viewModels{} is an extension function defined to be outside of the androidx.fragment.app class but still allows us to call it from it.
  • Next we have to talk about the curly braces.

The curly braces {}

  • In order for use to talk about the curly braces we need to talk briefly about lambda expression. A lambda expression is defined as a function literal and function literals are functions that are not declared but instead passed immediately as an expression. We can always identify a lambda expression, because they are always surrounded by curly braces. So in our example everything inside the {} is considered a lambda expression.
  • It should be pointed out that the piece of code in the curly braces is a lambda expression and we pass it as an argument to a function. In our case that function is viewModels. The reason for there not being a proper function call like, viewModels(){}, is because anytime a lambda is the only argument to a function we can remove the empty parentheses from the call. Within our lambda expression the last expression inside the lambda body is treated as the return value.

Conclusion

  • Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on Twitter.

Top comments (1)