How to use BLoC architecture in flutter – 1

BloC architecture - BloC is short form for Business Logic Component. As it name suggest, we will use it for separating business logic from presentation logic

BloC architecture – BloC is short form for Business Logic Component. As it name suggest, we will use it for separating business logic from presentation logic.created by Felix Angelov and was introduced at Google I/O in 2019. Hence Bloc is not architecture itself, we still need to organize our data according to DDD, MVVM or other.

We will not discuss Pros and Cons here, We will move straight to its implementation in our flutter app.

BloC architecture components

  • Event And Actions are input that appears when user interacts with app, like button click or scroll
  • State is reaction to these event, it changes according to event
  • A Bloc is responsible for business logic, It processes event and convert it into state
  • Stream is asynchronous flow of data that UI and Bloc reacts.

Add Bloc architecture to app

We will go step by step to implement architecture :

  1. Add Dependency
  2. Create Repositiory
  3. Add repository dependency
  4. Create BloC
  5. Use BloC
  1. Add Dependency
  flutter_bloc: ^7.0.0

2. Create Repository

├── android
├── ios
├── lib
├── packages
│   └── authentication_repository
└── test

We need to create pubspec.yaml for our new repository

name: authentication_repository
description: Dart package which manages the authentication domain.
publish_to: none

  sdk: ">=2.12.0-0 <3.0.0"

Now create AuthenticationRepository class file and enum for AuthenticationStatus in lib/src/ in our newly created package

enum AuthenticationStatus{
unknown, authenticated, unauthenticated

import 'dart:async';

import 'package:authentication_repository/src/AuthenticationStatus.dart';

class AuthenticationRepository{
  final _controller = StreamController<AuthenticationStatus>();

  Stream<AuthenticationStatus> get status async* {
    await Future<void>.delayed(const Duration(seconds: 1));
    yield AuthenticationStatus.unauthenticated;

  Future<void> login() async{
    await Future<void>.delayed(Duration(seconds: 1), (){

  Future<void> logout() async{
    await Future<void>.delayed(Duration(seconds: 1), (){

  void dispose(){

Next we need to create authentication_repository.dart file which contains public exports

library authentication_repository;

export 'src/AuthenticationRepository.dart';
export 'src/AuthenticationStatus.dart';

We also need UserRepository to display details according to user

├── android
├── ios
├── lib
├── packages
│   ├── authentication_repository
│   └── user_repository
└── test

pubspec.yaml for user_repository

name: user_repository
description: Dart package which manages the user domain.
publish_to: none

  sdk: ">=2.12.0-0 <3.0.0"

  equatable: ^2.0.0

user model class – we have used Equatable to compare User model (create in lib/src/model)

import 'package:equatable/equatable.dart';

class User extends Equatable {
  const User(;

  final String id;

  List<Object> get props => [id];

  static const empty = User('-');

now we need to create models.dart file in lib/src/model with below content

export 'user.dart';

Now UserRepository with singe method getUser for simplicity, you need to add more as your requirements.

import 'dart:async';
import 'models/models.dart';

class UserRepository {
  User? _user;

  Future<User?> getUser() async {
    if (_user != null) return _user;
    return Future.delayed(
      const Duration(milliseconds: 300),
      () => _user = User("#GeneratedUserId"),

now we only need user_repository.dart in lib folder to export our package.

library user_repository;

export 'src/models/models.dart';
export 'src/user_repository.dart';

Add Repository dependency

add following paths in your main pubspec.yaml file under dependencies, be careful about spacing. yaml file is very strict about it. it uses 2 space rule.

    path: packages/authentication_repository
    path: packages/user_repository

Don’t forgot to pub get after editing yaml file. Stay tuned with us for part2 of How to implement Bloc architecture in flutter app, Please always use latest version of library whenever you import dependency.

Share this content:


More Posts

How does data persistence work in Android?

Data persistence in Android is the ability to save data to the device so that it can be accessed later, even if the app is closed or the device is restarted. There are several ways to achieve data persistence in Android

Fragments and Activities: Two Pillars of Android Development

Fragments and Activities are both important components of Android development. Fragments are a good choice for creating reusable and dynamic UIs, while Activities are a good choice for managing the lifecycle of an app’s UI and implementing core features.

Table of Contents

Send Us A Message