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…
We’ll have following folders inside lib folder.
Inside ‘res’ folder, we’ll put constant values like strings, colors, arrays etc. For now, lets put the url in strings.dart file.
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.
Now, inside repository folder, create article_repository.dart file. Here we gonna parse the json and convert them into our desired model.
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 :
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 :
So now, let’s create an abstract class for state and extend that abstract class by the 4 state classes of our app.
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
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
initialStateis called even before any event has been processed. We are returning
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.
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.
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
Homepagewidget, we are using
BlocBuilder widget with
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
BlocListener is a widget where we can trace logs, show snackbars etc. One time actions can be performed inside
BlocListener. So now, lets wrap
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 :
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 :
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