Looking for great developers Looking for great developers [email protected]
Facebook Linkedin Dribbble Behance Cluth

Everything You Need to Know About BLoC State Manager in Flutter

20-04-2022 6 min read

Everything You Need to Know About BLoC State Manager in Flutter

Everyone likes it when there is order during work. Research shows that when a person has an orderly environment, he works more efficiently, faster, and is more focused. We, as one of the best product development company, know that mess in the workspace is a mess in code. And that's an unacceptable scenario

This is why organizing Business Logic with UI development is a key element of optimizing work on your project. Order can be maintained by using the appropriate tech stack. What is this? How does it work? You can find answers to these and many other tech stack-related questions in our article "How to choose a tech stack for your project?".

As code with literally everything is very hard to handle, it can slow down your work, and, on top of that, it can cause bugs or other threats. This is why the BLoC pattern is used so often during projects in Flutter.

What is Flutter?

Flutter lets you create a cross-platform app quickly. It is a widget-based solution to create UI and does not require using a bridge or native elements like React-Native. It speeds up development. But React-Native and Flutter have one thing in common: State Managing.

As React Native and Flutter are listed side by side, you might be curious about the difference, which is better and why. To answer these questions, we have created an article "Flutter vs. React Native: which one is better?" in which we cover everything you need to know about Flutter and React Native development.

Flutter can support almost or every state management approach. It depends on the team/developer. One of them which is very popular is BLOC.

I appreciate these words. The acronym means "Business logic component." It means more than model-view-ViewModel (MVVM), but it is almost identical to a class diagram. Logic is just separated from the view, and UI observes the state.

Two crucial types for asynchronous programming

two crucial types for asynchronous programming

Dart programming language contains two crucial types for asynchronous programming. Stream and Future. Stream is a sequence of results, and a single computation represents the Future. Under the hood is based on streams.

Bloc is an abstract class extending Cubit. Cubit is simply a solution with an editing state on request. UI calls the method, and Cubit emits the new state. Bloc organizes this more formally. In Bloc, you have to override the mapEventToState(event) method. This method yields forms in response to an event.

class MovieBloc extends Bloc<MoviesEvent, MoviesState> {

  final MovieRepository _movieRepository;

  MovieBloc(MoviesState initialState, this._movieRepository)

      : super(initialState);

  @override

  Stream<MoviesState> mapEventToState(MoviesEvent event) async* {

    yield* event.map(

      trendingOption: (_) async* {

        yield MoviesState.loading();

        var option = await _movieRepository.allAsOption();

        yield option.fold(

          () => MoviesState.error(),

          (movies) => MoviesState.loaded(movies),

        );

      },

    );

  }

}

Compare it to Cubit:

class MovieCubit extends Cubit<MoviesState> {

  final MovieRepository repository;

  MovieCubit({this.repository}) : super(LoadingMovies());

  void getMoviesByOption() async {

    emit(LoadingMovies());

    final movies = await repository.allAsOption();

     movies.fold(

      (movies) => emit(LoadedMovies(movies)),

      (error) => emit(LoadedErrorTyped(error)),

    );

  }
} 

HydratedBloc and ReplayBloc libraries

HydratedBloc or ReplayBloc

Using it, you have probably heard about HydratedBloc or ReplayBloc. These libs are helpful in a quick delivery state to remember or replaying. It works in both Cubit and Bloc. You have two more methods to override hydrated: toJson() and fromJson(). In toJson(), you are just saving the interesting state, for example, a list of movies. And fromJson() decode it to state.

Replay comes in undo/redo functions.

You have a few Bloc-specific widgets on the UI to listen to state changes.

For example, BlocBuilder:

BlocBuilder<MovieBloc, MoviesState>(

        cubit: _movieBloc,

        builder: (context, state) {

          if (state is LoadedMovies) {

            return MoviesGrid(movies: state.movies);

          } else if (state is EmptyListOfMovies) {

            return EmptyListInfoSafeArea();

          } else if (state is LoadedError || state is LoadedErrorTyped) {

            return ErrorSafeArea();

          }

          return LoadingSafeArea();

        }, 

     ),

Types are what kind of Bloc it is and what kind of state it is generating.

Cubit just passed a reference to Bloc. It's a helpful tip not to generate Bloc on your UI page. I enjoy the get_it package, where you can easily manage your dependencies and inject what you need in your Bloc. Just call the dependency container to get one.

It very easily one-liner: final MovieBloc _movieBloc = getIt();

And MovieBloc comes in with injected repository (you need to define it on your container), as you can see.

  final MovieRepository _movieRepository;

 

  MovieBloc(MoviesState initialState, this._movieRepository)

      : super(initialState);

Testing of the Bloc is easy too

Testing of the Bloc

Like always, in Flutter space with an incredible community of pub.dev there is a superb transparent tool to test your Blocs. It is called Bloc_test.

So with MovieBloc, we inject a real movie repository that injects real data sources. So how do you test it and ensure the Bloc works well without making an actual network connection on any other third dependent stuff?

It's something I wrote a little in the "Don't use injection for testingarticle.

Bloc Test comes with an excellent structure for testing:

   blocTest(

      'emits [LoadingMovies, LoadedError] when repository return a none  from Option',

      build: () {

        when(mockRepository.allOption()).thenAnswer((_) async => none());

        return bloc;

      },

      act: (bloc) => bloc.add(LoadingMoviesByOption()),

      expect: [

        LoadingMovies(),

        LoadedError(),

      ],
    ); 

Build test with a mocked response. Act a blog bypassing event or request Cubit. And watch expected states.

Conclusion

The presented methods of using BLoC will certainly make it easier for you to work on your project and organize the code that may be viewed by someone from outside in the future. Someone who could lend a helping hand during development problems. As an offshore outsourcing company, we are experts in helping with custom mobile development, so we know how various adversities can happen when creating your project.

Bloc is a great structured way to manage states in Flutter easily. To build native mobile apps in record time - with a testable structure and changeable environment to pass your client's expectations. Comes with a great community like a Flutter. So I can thoroughly recommend it to your team.

 
mDevelopers

Software development company

Go to clutch mdevelopers

We’ve been in the business for over 12 years and have delivered over 200 mobile and web projects. We know what it takes to be a reliable software partner.

Let our people take your business to the next level.

Sounds interesting? Give us some details and get your free estimation.

Cookies.

By using this website, you automatically accept that we use cookies. What for?

Understood