Bloc Architecture, Access, and Routing
This is the second/intermediate part of our blog on Bloc Pattern. For basics please refer to Bloc Basics
Architecture is how we pre-plan locate components of our code to make our code well structured and easily readable. It could be done by separating the code into layers representing different aspects of our code.
Bloc Architecture
Data Layer
Data Layer is responsible for receiving and manipulating data from network requests, databases, or other asynchronous sources. It is further divided into three sublayers: Models, Data Providers, and Repositories.Models
Bloc Architecture comprises three layers: Presentation Layer, Business Logic Layer, and Data Layer. Each layer holds a different purpose in our code and is put into different folders.
Model is a blueprint to the data your application will work with. It is the first process we do after visually and technically designing our brand new app. It is a class where we add all the data structures we need for our app. These attributes are linked to data we are receiving from our data sources. E.g., if we are making a weather app and using an AccuWeather API to fetch the data, we will create attributes like temperature, wind speed, etc. They should be generic and universal to data sources cause the app can be fetching data from multiple API s at the same time.
Data Providers
Data Providers request data from the data sources for the app in the form of raw JSON strings. It is like API for our app cause any data for our app is provided through data providers.
Repositories
A repository is a class where dependencies from data providers are used to get respective data. The received data is first converted from JSON string to model data form and fine-tuned and filtered according to our needs. Then data is stored in respective model object variables. These parts of the data layer the Bloc communicates with.
Business Logic Layer
In this layer, most of the blocs and cubits are present. It responds to user inputs from the presentation layer and emits states. It is a mediate layer between the beautiful UI and unstable data layers.
Presentation Layer
This layer consists of the widgets and classes responsible for the UI visible to the user while operating the app.
Bloc Access and Routing
Navigating from one screen of the app to other using routes provided is called Routing. When we navigate from one screen to another, our Bloc instance from the previous screen gets closed automatically by BlocProvider, due to which our states from the previous screen fail to reach our new screen, and thus, the app crashes. To solve this problem, we use Bloc BlocProvider.value. However, as the BlocProvider will not close our Bloc automatically, we will need to use :
void dispose() {
_cubitA.close();
super.dispose();
}
There are three different methods for routing in Flutter.
1. Anonymous Routing
2. Named Routing
3. Generated Routing
Anonymous Routing
We are passing the value of an instance to another screen without using any route name for our second screen.
Named Routing
We create a list of routes we navigate in the Material App Widget's 'routes' parameter. If we need to use the same Bloc instance for two or more routes, we will create it beforehand and pass it to those routes.
Generated Routing
We integrate the entire navigation feature for our app into a single file and function. Generated Routing declutters the main.dart file and makes code more readable and easier to maintain. In Material App, instead of routes parameter, we now use the 'onGenerateRoute' parameter and give the object of the class in which we include route names:
onGenerateRoute: _appRouter.onGenerateRoute,
Global Access
Suppose we want to use the same Bloc Instance for all of the screens in our app, like for Authentication Bloc. In that case, we will use global Access by wrapping our complete material app with BlocProvider or MultiBlocProvider. This way, we will not even need to close the Bloc manually.