Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/md-siam/bloc_concept

This repository is for understanding the core concepts of BLoC pattern in flutter.
https://github.com/md-siam/bloc_concept

Last synced: 9 days ago
JSON representation

This repository is for understanding the core concepts of BLoC pattern in flutter.

Awesome Lists containing this project

README

        

  
  
  
  

# BLoC - [Udemy](https://www.udemy.com/course/bloc-from-zero-to-hero/)

This tutorial video is also available on [youtube](https://www.youtube.com/watch?v=THCkkQ-V1-8). If you want, then instead of buying the Udemy tutorial, you can follow the youtube tutorial. The full documentation on BLoC package is available in [bloclibrary.dev](https://bloclibrary.dev/).

Bloc was designed with three core values in mind:

```
1. Simple: Easy to understand & can be used by developers with
varying skill levels.

2. Powerful: Help make amazing, complex applications by composing
them of smaller components.

3. Testable: Easily test every aspect of an application so that we
can iterate with confidence.
```

**Overall, Bloc attempts to make state changes predictable by regulating when a state change can occur and enforcing a single way to change state throughout an entire application.**

## BLoC Core Concept

**1. Stream:**

It is the foundation of BLoC. The stream is a river , which transport some data, on a boat, from the sender to the receiver. The transported data is asynchronous.

**2. Cubit:**

A cubit is the minimal version of a BLoC. BLoC actually extends cubit.

**3. Bloc:**

BLoC is the big brain of the project. Where as cubit is used to optimize the functionality of the project.

\*\*Note: Start with a cubit. If you see the necessity, then modify your cubit into BLoC.

## Flutter BLoC Concept


Some vital Flutter concepts to get going (widget, widget tree).

1. BlocProvider + CounterApp implementation.
2. BlocBuilder + CounterApp implementation.
3. BlocListener + CounterApp implementation.
4. BlocConsumer + CounterApp implementation.
5. RepositoryProvider
6. MultiBlocListener, MultiBlocProvider, MultiRepositoryProvider

**`RepositoryProvider` is a class. Which has the main function which makes flutter communicate with outer data layer i.e. internet, APIs, databases, etc.**



BlocBuilder & BlocListener can be combined together to from BlocConsumer

## BLoC Architecture



BLoC follows a specific folder pattern. The "Business logic" layer is separated from the "Presentation" layer and from the "Data" layer.

 1. First design the models. A model is a `blueprint` of the data an application will work with.


 2. Next the data providers. The data providers' responsibility is to provide raw data to it's successor, which is the `repositories`. It is actually an `API` for our own application.


 3. The repository is mainly a `wrapper` around one, or more data providers. Repositories are also `classes`, which contains dependencies of the respective data providers.

## BLoC Testing

A test is defined by how we programmatically tell flutter to `double check` the output given by a feature is equal to the expected response we planned on receiving. Packages needed for testing a BLoC:

```yaml
dependencies:
flutter:
sdk: flutter
# Helpful for testing equal instances
equatable: ^2.0.3
# For testing
bloc_test: ^9.0.3
```

In Dart language, **TWO INSTANCES** of the same exact class are not equal even though they are basically identical. This is because, these two instances are stored in different part of the memory, and dart compares their location in memories instead of their value.

Hence, we need `equatable` package to solve this problem. Equatable package simply `@overrides` the equal operator.

```dart
CounterState stateA = CounterState(counterValue:0);
CounterState stateB = CounterState(counterValue:0);

statA != stateB
```

## BLoC Access

```
BlocProvider() vs BlocProvider.value()

- BlocProvider() -> Necessary when transferring state to the HomeScreen()
- BlocProvider.value() -> Necessary for transferring state to the SecondScreen() & also
to the ThirdScreen()
```

- **Local Access:** Providing an instance of bloc/cubit to a `SINGLE SCREEN` is called local access. Example: wrapping the `HomeScreen()` with BlocProvider().

- **Route Access:** Providing an instance of bloc/cubit to `MULTIPLE SCREEN` is called route access. Example: wrapping the `SecondScreen()` & `ThirdScreen()` with BlocProvider.value().

- **Global Access:** Providing am instance of bloc/cubit to `EVERY SCREEN` to your application. Example: wrapping the `MaterialApp()` with `BlocProvider()` or `MultiBlocProvider()`.

Three types of routing option in Flutter:

1. Anonymous routing: Navigation WITHOUT a RouteName.
2. Named routing: Navigation WITH a RouteName. Recommended for small & medium size project.
3. Generated routing: Separating the route information into a separate file. Recommended for large size project.

## BLoC Communication



A Bloc/Cubit can communicate with each other using `StreamSubscription` or `BlocListener`. Both methods are equally good with their specific PROS/CONS

PROS of `StreamSubscription`:

- organized, structured, easy to read & maintain.
- will help us practice stream skills.

CONS of `StreamSubscription`:

- it may get cluttered really fast on huge apps
- not closing streamSubscription => huge memory leaks


----------------------------------------------- xxxx -----------------------------------------------

`BlocListener` is a widget, hence it should be inside the widget tree. This just notifies the bloc/cubit. It tells the bloc/cubit what to do, not how to do it.

PROS of `BlocListener`:

- It takes care internally of all STREAMSubscriptions
- No need to take care of stream/memory leaks anymore

CONS of `BlocListener`:

- The UI may get cluttered & hard to read with multiple BlocListener

## BuildContext In-Depth

The `BuildContext` is a tool which helps handle the location of the widget inside the widget tree. That means every widget is build within a BuildContext.

One of the most common ERROR of bloc/cubit is:

```dart
"BlocProvider.of() fails to find
a context containing a specific
bloc/cubit"
```

A BuildContext of a widget keeps tract only of their direct `parent` and nothing else. Hence, the relationship between the BuildContext is a bottom-up relationship.

Fow of the BLoC `contexts` introduced in bloc: ^6.1.0:

1. context.watch()
2. context.select()
3. context.read()

## Hydrated BLoC

Hydrated BLoC is used mainly for storing the state of a bloc/cubit. `hydrated_bloc` exports a `Storage` interface which means it can work with any storage provider. Out of the box, it comes with its own implementation: `HydratedStorage`.

`HydratedStorage` is built on top of **_HIVE_** for a platform-agnostic, performant storage layer. See the complete example for more details.

Packages necessary for using hydrated bloc are:

```yaml
# For storing state into the device
hydrated_bloc: ^8.1.0
# For retrieving path for data storage
path_provider: ^2.0.11
```

## BLoC Debugging



## App Screenshots


Folder No.
Name of the App
Logic Files
Screenshots


3
Counter Using Cubit

counter_cubit.dart

counter_state.dart




5
BLoC Testing

counter_cubit.dart

counter_state.dart




6
BLoC Access & Route

counter_cubit.dart

counter_state.dart




7.0
BLoC Communication
using
StreamSubscription


counter_cubit.dart

counter_state.dart

internet_cubit.dart

internet_state.dart




7.1
BLoC Communication
using
BlocListener


counter_cubit.dart

counter_state.dart

internet_cubit.dart

internet_state.dart




10
State Not Updating

settings_cubit.dart

settings_state.dart




11
Hydrated BLoC

counter_cubit.dart

counter_state.dart




12
Debugging

counter_state.dart

internet_state.dart

settings_state.dart