Implementing BLoC Pattern for parsing JSON from API

Newaj kabir
Flutter Community
Published in
5 min readDec 5, 2019

Developers should follow a state management procedure. A pattern makes the project scalable, readable and and maintainable. So far, lots of pattern available for managing state in Flutter. Here we are going to see the implementation of BLoC pattern. BLoC pattern is a design pattern for separating business logic from UI layer. Fortunately there is a package available for simplifying the process of implementing BLoC pattern, which is flutter_bloc. I am going to fetch data from this API. So let’s get started!

Project Overview: Our app will have 2 screens. Homescreen will have a list of articles, upon click on the list item, user will be navigated to the second screen. Second screen will contain the details of the article.

BLoC overview: Lets have a brief overview of the flutter_bloc package. A BLoC takes stream of events as inputs and converts them into stream of states as outputs. This package abstracts the reactive aspects of the BLoC pattern. Lets have a quick view on some important terms.

EVENTS: Input to a BLoC is known as event. These are actions on screen, such as button click.

STATES: States are the output of Bloc. In BLoC pattern, user interface(UI) is changed based on the stream of received states.

So now, lets start coding…

First, let’s add flutter_bloc package in pubspec.yaml file. Additionally lets add equatable package, which is for comparing value equality of objects.

dependencies:
flutter:
sdk: flutter
http: ^0.12.0
flutter_bloc: ^2.0.0
equatable: ^0.6.1

PROJECT STRUCTURE

We’ll have following folders inside lib folder.

- res
- data
- bloc
- ui

Inside ‘res’ folder, we’ll put constant values like strings, colors, arrays etc. For now, lets put the url in strings.dart file.

strings.dart

Inside data folder, we’ll have a models folder and repositories folder. Lets create api_result_model.dart file inside model folder. We’ll use this tool for converting json to dart object. So let’s put converted model class inside api_result_model.dart file.

api_result_model.dart

Now, inside repository folder, create article_repository.dart file. Here we gonna parse the json and convert them into our desired model.

article_repository.dart

Here inside getArticles()method, we are converting json reponse into a list a of ‘Articles’ object. Now, our ‘data’ folder is completely ready.

Now, let’s move on to the core of this article, BLoC.

In this particular app, we need only a single BLoC, which is for fetching articles from API and showing them in a ListView. So now create article_bloc folder inside blocs folder. Let’s create three files inside article_bloc folder : article_event.dart, article_state.dart and article_bloc.dart.

Events: In this app we have a single event which is fetching articles. We gonna create abstract classes both for the events and states, and then respective events and states gonna extend those abstract classes. Here is the abstract event class with the single event :

article_event.dart

States: Now think about the states of the app. Parsing the articles will definitely take some times. So initially there will be a loading indicator. And then articles may be fetched successfully or some errors may interrupt. So two more states for success and errors. Additionally another state need to be added for initial moment. So we will have 4 states :

  • ArticleInitialState
  • ArticleLoadingState
  • ArticleLoadedState
  • ArticleErrorState

So now, let’s create an abstract class for state and extend that abstract class by the 4 state classes of our app.

article_state.dart

If parsing goes successful, ArticleLoadedState will handle a list of Articles, and if error occurs, ArticleErrorState will show an error message. That’s why the classes have List<Articles> and a Stringfield respectively.

Now come to the article_bloc file. Here we have created our bloc which extends the Bloc class. We need to mention the event and state as type parameter. Also we need to override the initialStateand mapEventToState methods. initialStateis called even before any event has been processed. We are returning ArticleInitialStatefrom initialState method.

mapEventToState is a must to implement. It takes events as stream and converts them into states as streams which are consumed by presentation layer. mapEventToState is called whenever an event is added by presentation layer.

article_bloc.dart

Here in this case, initially when the event is added, ArticleLoadingStateis yielded. After fetching articles successfully, ArticleLoadedStateis yielded. If error occurs, then ArticleErrorState will be yielded. So now bloc part of our app is ready!

Now time to complete the presentation layer.

main.dart: We are going to use the BlocProviderwidget from flutter_bloc package in order to make the instance of ArticleBlocavailable to the entire subtree.

main.dart

BlocProvider is used to build ArticleBlocwhich is now available to the rest of the subtree. BlocProviderwill automatically close the ArticleBloc, so we don’t need to use a StatefulWidget. But our Homepageis instead a StatefulWidget. Reason is, there is no user action initially when the api gets called. So, we need to call bloc from initState().

home_page.dart:

home_page.dart

Inside the build()method of Homepagewidget, we are using BlocBuilder widget with ArticleBlocand ArticleStateas type parameter. BlocBuilder takes an optional ‘bloc’ parameter. But as we’ve specified the type of the bloc and the type of the state, BlocBuilderwill find the bloc. So we dont need to use ‘bloc’ parameter. Inside builder parameter, we are checking state and returning appropriate UI based on the state.

ONE LAST THING…

Additionally we can use the BlocListenerwidget. BlocListener is a widget where we can trace logs, show snackbars etc. One time actions can be performed inside BlocListener. So now, lets wrap BlocBuilderwith BlocListener to show a snackbar on ArticleErrorState. Additionally, a ‘refresh’ icon is added on AppBar where onTap()call the event again. So our final build()will look like this :

home_page.dart

Now, the only remaining task is — adding the event to the ArticleBloc. For that, we gonna have an instance of ArticleBloc. We’ll initialize it and add event to it inside initState() method :

home_page.dart

So that’s all! Business logic is now separated from the presentation layer.

Full source code here : https://github.com/newajthevillager/Flutter-Json-Parsing-with-BLoC

Full explanation in Youtube : https://www.youtube.com/watch?v=27EP04T824Y&t=9s

--

--