Flutter: MVVM architecture best practice using Provide & HTTP

Maraj Hussain
4 min readSep 7, 2021

--

Application design

Flutter is Google’s platform-independent technology to create a mobile application (Android & iOS) as well as for web applications.

Why do we need MVVM in flutter?
As we know that flutter does not support any architecture for the development. This means developers have a responsibility to implement it.

We need an architecture to communicate between the UI & business logic so MVVM is proving this in an easy way as you can hold your all business logic inside the ViewModel class and UI separately.

The key benefit of using MVVM are:

  1. Business logic is separate from the UI
  2. The view is independent from the ViewModel class and only reading the state from ViewModel
  3. Code will be easy to maintain and update in terms of logic & UI
  4. Easy to Write the test cases for the project

MVVM (Model-View-ViewModel)

MVVM Architecture

Model

This layer is responsible to fetch the data from the server or local DB and transfer to the ViewModel.
In this layer, we define the Network, Local DB, and Repository for communicating with API, DB, etc.

ViewModel

ViewModel is used to transfer data between View and Model, which accept all the user events and request that to Model for data response. Once the Model has data then it returns to ViewModel and then ViewModel notifies that data to View.

ViewModel can be used by multiple views, which means a single ViewModel can provide data to more than one View.

View

The view is where the user interacting with Widgets that are shown on the screen. User event request for some data from ViewModel, and the rest of ViewModel process the event as per the request to Model. Once the ViewModel gets the data from the model as requested then it reflects on the user view.

Now, we are going to see the example which will demonstrate MVVM architecture, for notifying data we will use the Provider, and for requesting server requests using the HTTP package.
Also, we are using a repository layer to complete the request and transfer the data back to View through ViewModel.

MVVM Architecture :

Our MVVM architecture look like below and now i briefing the folder structure for understanding the things to be used as best practice for MVVM

data: This directory will hold all the network & local DB-related classes.

models: This directory will hold all the model classes for the API response and for clean architecture create inner directories for each API response model class.

repository: This directory will hold all the repository classes used in the project for communicating with ViewModel and for clean architecture create an inner directory for each module of your project.

res: This directory will hold all the classes related to the colors, dimensions & strings files.

utils: This will hold all the Utility classes for the project.

view: this directory will hold all the view-related classes with subdirectory as per the module & widget as well for the project.

view_model: this directory will hold all the ViewModel-related classes with subdirectory if required.

Now move to the coding part :)

NetworkApiService.dart

This is the generic class that handles all the network requests and communicates with ViewModel through a repository class.

In our demo, we are using only the GET request but you can add all the requests in BaseApiService like POST, PUT, DELETE, etc.

BaseApiService.dart

ApiEndPoints.dart

All the endpoints for the API will be added in this class only

MovieRepoImp.dart

This is the repository layer which will be responsible to communicate with network layer and transfer data to ViewModel class on request.

MovieListVM.dart

This class used provider package class ChangeNotifier and we are calling this class ViewModel which is responsible to call the repository method and take the response from there and transfer the same data to View. Also, we managing the View state from here.

We have updated our MoviesListVM to inherit from ChangeNotifier. ChangeNotifier allows us to publish changes, which can be used by the view.

After we fetch the movies list using the repository, we call the notifyListeners() function, notifying all the subscribers/listeners.

ApiResponse.dart

This is the generic response class for the API response with generic data and also has three states loading, complete & error which help us to manage the view as per the API state.

Status.dart

This is the enum for handling multiple states for the UI section like Loading, Complete & Error.

HomeScreen.dart

This is the view for the list which display the data and also show the state of API by using provider state in it.
In this class, we have created an instance of the ViewModel class and observe the changing state using ChangeNotifierProvider and consume all the states in it.

In order to notify the view with the updated MoviesListVM, we’ll have to use the ChangeNotifierProvider, which is part of the Provider package. Add the provider package by adding the dependency in the pubspec.yaml file, as shown below:

The full repository code is here!

Thanks for reading!

--

--