androidmvvmandroid-architecture-componentsandroid-architecture

Is it ok for view to ask for data from ViewModel in MVVM?


I have been reading about MVVM pattern. View is supposed to observe for changes in ViewModel and act on it accordingly but I am confused if following code in View is ok in MVVM architecture.

fun onClick(view:View){
    showUser(viewModel.getUserDisplayName())
}

Here View is not observing for a change, its rather asking for latest data from ViewModel. Is this considered correct in MVVM?


Solution

  • This is a question that possibly has no one answer, as different points might be made depending on the exact use case. However:

    Sir Codesalot (great handle) is in my opinion technically correct. Let me elaborate.

    In MVVM the view should pass UI interaction events (commands) to the ViewModel. Here is an article from microsoft (who invented mvvm): https://msdn.microsoft.com/en-us/library/ff798384.aspx The examples here are not related to android, but the concepts should be the same, especially if you look at the first diagram.

    The ViewModel should do its magic, react to these events by manipulating data accordingly and then notify the observers (usually the view) of state changes. The view then reacts to the state changes.

    In this way, if you would just pass data back from the ViewModel (in a synchronous way), then your view might be missing side effects. In your particular example, there probably aren't any, but consider that the method you call does not only return data, but also changes some internal state (e.g. counts the number of times the data was accessed). Then your view will not know of these.

    Of course, you can make the case, that you can return all relevant data for the view, but it starts to break the single responsibility principle.

    Here is an interesting blog post, which might give a better example, why the view should always get the state after the ViewModel: https://medium.com/upday-devs/mvvm-rxjava-learnings-1819423f9592

    To the point of the other case, the wikipedia article about MVVM https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel states, that the ViewModel can expose public properties.

    So in the end, it will most probably be cleaner if you do not return data directly. However, you are the architect and you know your app the best and there might be cases where patterns can be broken. After all they are guidelines. If you know why you break it (and maybe document it), then everything should work out.