Architect Your Flutter Project Using BLOC Pattern - FlutterPub - Medium
Architect Your Flutter Project Using BLOC Pattern - FlutterPub - Medium
Hi Folks! I am back with another brand new article on Flutter. This time I will be
talking and demonstrating to you “how to architect your Flutter projects”. So that you
can maintain, scale and test your Flutter projects easily. Before diving into the actual
topic. I would like to share a small story on why we should focus on building a solid
architect of our projects.
Update: Part 2 and Part 3 of this article has be published with some changes in the current
design to address some issues and to showcase some amazing implementations. Here is the
link.
Part 3
Part 4
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 1/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
Putting an end to my boring story 😅. Let’s start working on the main goal of this
article. “Architect your Flutter projects using BLOC pattern”.
Our Goal
I will be building a very simple app. It will have one screen where you can see a grid list
of items. Those items will be fetched from the server. The list of items will be popular
movies from The Movies DB site.
Note: Before moving any further I assume you understand Widgets, how to make a
network call in Flutter and have intermediate knowledge in Dart. This article will be a
little lengthy and heavily hyperlinked to other resources so that you can read further on
specific topics.
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 2/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
The above diagram shows how the data flow from UI to the Data layer and vice versa.
BLOC will never have any reference of the Widgets in the UI Screen. The UI screen will
only observe changes coming from BLOC class. Let’s have a small Q&A to understand
this diagram:
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 3/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
Its a state management system for Flutter recommended by Google developers. It helps
in managing state and make access to data from a central place in your project.
. . .
. . .
3. What is under the hood of BLOC ? or What is that core thing that
manages the state in one place?
STREAMS or REACTIVE approach. In general terms, data will be flowing from the
BLOC to the UI or from UI to the BLOC in the form of streams. If you have never heard
about streams. Read this Stack Overflow answer.
. . .
Hope this small Q&A section cleared some of your doubts. If you need further clarity or
want to ask a specific question, you can comment down below or connect directly with
me at LinkedIn.
1. First create a new project and clear all the code in the main.dart file. Type below
command in your terminal:
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 4/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
import 'package:flutter/material.dart';
import 'src/app.dart';
void main(){
runApp(App());
}
You must be getting an error in the second line. We will solve it in the upcoming steps.
3. Create a src package under the lib package. Inside src package create a file and name it
as app.dart. Copy paste the below code inside the app.dart file.
import 'package:flutter/material.dart';
import 'ui/movie_list.dart';
4. Create a new package inside the src package and name it as resources.
Now create few new packages i.e blocs, models, resources and ui as shown in the below
diagram and then we are set with the skeleton of the project:
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 5/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
Project structure
blocs package will hold our BLOC implementation related files. models package will
hold the POJO class or the model class of the JSON response we will be getting from
the server. resources package will hold the repository class and the network call
implemented class. ui package will hold our screens that will be visible to the user.
5. One last thing we have to add i.e RxDart a third party library. Open your
pubspec.yaml file and add rxdart: ^0.18.0 as shown below:
dependencies:
flutter:
sdk: flutter
sync your project or type below command in terminal. Make sure you execute this
command inside your project directory.
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 6/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
6. Now we are complete with the skeleton of the project. Time to deal with the most bottom
layer of the project i.e the network layer. Let’s understand the API end point which we are
going to consume. Hit this link and you will be taken to the movie database API site. Sign
up and get your API key from the Settings page. We will be hitting the below url to get the
response:
http://api.themoviedb.org/3/movie/popular?api_key=“your_api_key”
Put your API key in the above link and hit(Remove double quotes as well). You can see
the JSON response something like this:
{
"page": 1,
"total_results": 19772,
"total_pages": 989,
"results": [
{
"vote_count": 6503,
"id": 299536,
"video": false,
"vote_average": 8.3,
"title": "Avengers: Infinity War",
"popularity": 350.154,
"poster_path": "\/7WsyChQLEftFiDOVTGkv3hFpyyt.jpg",
"original_language": "en",
"original_title": "Avengers: Infinity War",
"genre_ids": [
12,
878,
14,
28
],
"backdrop_path": "\/bOGkgRGdhrBYJSLpXaxhXVstddV.jpg",
"adult": false,
"overview": "As the Avengers and their allies have continued
to protect the world from threats too large for any one hero to
handle, a new danger has emerged from the cosmic shadows: Thanos. A
despot of intergalactic infamy, his goal is to collect all six
Infinity Stones, artifacts of unimaginable power, and use them to
inflict his twisted will on all of reality. Everything the Avengers
have fought for has led up to this moment - the fate of Earth and
existence itself has never been more uncertain.",
"release_date": "2018-04-25"
},
7. Let’s build a model or POJO class for this type of response. Create a new file inside the
models package and name it as item_model.dart. Copy and paste the below code inside
item_model.dart file:
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 7/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
class ItemModel {
int _page;
int _total_results;
int _total_pages;
List<_Result> _results = [];
class _Result {
int _vote_count;
int _id;
bool _video;
var _vote_average;
String _title;
double _popularity;
String _poster_path;
String _original_language;
String _original_title;
List<int> _genre_ids = [];
String _backdrop_path;
bool _adult;
String _overview;
String _release_date;
_Result(result) {
_vote_count = result['vote_count'];
_id = result['id'];
_video = result['video'];
_vote_average = result['vote_average'];
_title = result['title'];
_popularity = result['popularity'];
_poster_path = result['poster_path'];
_original_language = result['original_language'];
_original_title = result['original_title'];
for (int i = 0; i < result['genre_ids'].length; i++) {
_genre_ids.add(result['genre_ids'][i]);
}
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 8/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
_backdrop_path = result['backdrop_path'];
_adult = result['adult'];
_overview = result['overview'];
_release_date = result['release_date'];
}
I hope you can map this file with the JSON response. If not, we are mostly interested in
the poster_path inside the Results class that’s what you need to know to move further.
We will display all the posters of popular movies in our main UI. fromJson() method is
just getting the decoded JSON and putting the values in the correct variables.
8. Now its time to work on the network implementation. Create a file inside the resources
package and name it as movie_api_provider.dart. Copy and paste the below code inside
the file and I will explain it to you:
import 'dart:async';
import 'package:http/http.dart' show Client;
import 'dart:convert';
import '../models/item_model.dart';
class MovieApiProvider {
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 9/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
Note: Please put your API key in the variable _apiKey inside the
movie_api_provider.dart file or else it won’t work.
fetchMovieList() method is making the network call to the API. Once the network call
is complete it’s returning a Future ItemModel object if the network call was successful
or it will throw an Exception.
9. Next we are going to create a new file inside the resources package and name it as
repository.dart. Copy and paste the below code inside the file:
import 'dart:async';
import 'movie_api_provider.dart';
import '../models/item_model.dart';
class Repository {
final moviesApiProvider = MovieApiProvider();
method. This Repository class is the central point from where the data will flow to the
BLOC.
10. Now comes a little complicated part. Implementing the bloc logic. Let’s create a new file
inside the blocs package and name it as movies_bloc.dart. Copy paste below code and I
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 10/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
import '../resources/repository.dart';
import 'package:rxdart/rxdart.dart';
import '../models/item_model.dart';
class MoviesBloc {
final _repository = Repository();
final _moviesFetcher = PublishSubject<ItemModel>();
fetchAllMovies() async {
ItemModel itemModel = await _repository.fetchAllMovies();
_moviesFetcher.sink.add(itemModel);
}
dispose() {
_moviesFetcher.close();
}
}
responsibility is to add the data which it got from the server in the form of ItemModel
object and pass it to the UI screen as a stream. To pass the ItemModel object as stream
we have created another method allMovies() whose return type is Observable(watch
this video if you don’t understand Observables). If you see the last line we are creating
the bloc object. This way we are giving access to a single instance of the MoviesBloc
class to the UI screen.
If you don’t know what reactive programming is. Please read this simple explanation.
In simple words, whenever there is new data coming from the server. We have to
update the UI screen. To make this updating task simple we are telling the UI screen to
keep observing any change coming from the MoviesBloc class and accordingly update
your content. This “observing” of new data can be done using RxDart.
11. Now the last section. Create a new file inside the ui package and name it as
movie_list.dart. Copy paste the below code:
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 11/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
import 'package:flutter/material.dart';
import '../models/item_model.dart';
import '../blocs/movies_bloc.dart';
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 12/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
One thing to point here, that I am making a network call inside the build method which
should not be done as build(context) a method can be called multiple times. I will be
updating this article with a better approach. But for now, as the article is getting big
and complicated I am keeping things simple i.e making the network call inside the
build(context) method.
As I told you, our MoviesBloc class is passing the new data as a stream. So to deal with
streams we have a nice inbuilt class i.e StreamBuilder which will listen to the incoming
streams and update the UI accordingly. StreamBuilder is expecting a stream parameter
where we are passing the MovieBloc’s allMovies() method as it is returning a stream.
So the moment there is a stream of data coming, StreamBuilder will re-render the
widget with the latest data. Here the snapshot data is holding the ItemModel object.
Now you can you any Widget to display whatever is there in the object(Here your
creativity comes into the picture). I used a GridView to display all the posters that are
there in the results list of ItemModel object. This is the output of the final product:
Small demo. The video was not capturing the complete frames I guess 😐
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 13/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
So we have hit the end of this article. Great job folks for holding on till the end. Hope
you like this article. If you have any doubts or questions do connect with me at
LinkedIn or Twitter. Do appreciate the article with some claps and comments.
If you want the complete code. Here is the github repository of the project.
medium.com
. . .
The Flutter Pub is a medium publication to bring you the latest and amazing resources
such as articles, videos, codes, podcasts etc. about this great technology to teach you
how to build beautiful apps with it. You can find us on Facebook, Twitter, and Medium
or learn more about us here. We’d love to connect! And if you are a writer interested in
writing for us, then you can do so through these guidelines.
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 14/15
07/02/2020 Architect your Flutter project using BLOC pattern - FlutterPub - Medium
https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1 15/15