# bloc 7.0.0-nullsafety.0

A predictable state management library that helps implement the BLoC (Business Logic Component) design pattern.




## Installing
```
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add 'bloc:7.0.0-nullsafety.0'
```
Published: 2020-11-22T06:18:04.019810Z
Expected archive SHA-256: d9d8220e723c09c76dead9a2cbfcdea5c953fb5ee37e8115063f264d09554ea5

Available in cache; verification: upstream_checksum
## Direct dependencies
- meta: ^1.3.0-nullsafety.6

## Package README (untrusted upstream documentation)
<p align="right">
<a href="https://flutter.dev/docs/development/packages-and-plugins/favorites"><img src="https://raw.githubusercontent.com/felangel/bloc/master/docs/assets/flutter_favorite.png" width="100" alt="build"></a>
</p>

<p align="center">
<img src="https://raw.githubusercontent.com/felangel/bloc/master/docs/assets/bloc_logo_full.png" height="100" alt="Bloc" />
</p>

<p align="center">
<a href="https://pub.dev/packages/bloc"><img src="https://img.shields.io/pub/v/bloc.svg" alt="Pub"></a>
<a href="https://github.com/felangel/bloc/actions"><img src="https://github.com/felangel/bloc/workflows/build/badge.svg" alt="build"></a>
<a href="https://codecov.io/gh/felangel/bloc"><img src="https://codecov.io/gh/felangel/Bloc/branch/master/graph/badge.svg" alt="codecov"></a>
<a href="https://github.com/felangel/bloc"><img src="https://img.shields.io/github/stars/felangel/bloc.svg?style=flat&logo=github&colorB=deeppink&label=stars" alt="Star on Github"></a>
<a href="https://github.com/tenhobi/effective_dart"><img src="https://img.shields.io/badge/style-effective_dart-40c4ff.svg" alt="style: effective dart"></a>
<a href="https://flutter.dev/docs/development/data-and-backend/state-mgmt/options#bloc--rx"><img src="https://img.shields.io/badge/flutter-website-deepskyblue.svg" alt="Flutter Website"></a>
<a href="https://github.com/Solido/awesome-flutter#standard"><img src="https://img.shields.io/badge/awesome-flutter-blue.svg?longCache=true" alt="Awesome Flutter"></a>
<a href="https://fluttersamples.com"><img src="https://img.shields.io/badge/flutter-samples-teal.svg?longCache=true" alt="Flutter Samples"></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-purple.svg" alt="License: MIT"></a>
<a href="https://discord.gg/Hc5KD3g"><img src="https://img.shields.io/discord/649708778631200778.svg?logo=discord&color=blue" alt="Discord"></a>
<a href="https://github.com/felangel/bloc"><img src="https://tinyurl.com/bloc-library" alt="Bloc Library"></a>
</p>

---

A dart package that helps implement the [BLoC pattern](https://www.didierboelens.com/2018/08/reactive-programming---streams---bloc).

**Learn more at [bloclibrary.dev](https://bloclibrary.dev)!**

This package is built to work with:

- [flutter_bloc](https://pub.dev/packages/flutter_bloc)
- [angular_bloc](https://pub.dev/packages/angular_bloc)
- [bloc_test](https://pub.dev/packages/bloc_test)
- [hydrated_bloc](https://pub.dev/packages/hydrated_bloc)
- [replay_bloc](https://pub.dev/packages/replay_bloc)

## Overview

The goal of this package is to make it easy to implement the `BLoC` Design Pattern (Business Logic Component).

This design pattern helps to separate _presentation_ from _business logic_. Following the BLoC pattern facilitates testability and reusability. This package abstracts reactive aspects of the pattern allowing developers to focus on writing the business logic.

### Cubit

![Cubit Architecture](https://raw.githubusercontent.com/felangel/bloc/master/docs/assets/cubit_architecture_full.png)

A `Cubit` is the base for `Bloc` (in other words `Bloc` extends `Cubit`). `Cubit` is a special type of `Stream` which can be extended to manage any type of state. `Cubit` requires an initial state which will be the state before `emit` has been called. The current state of a `cubit` can be accessed via the `state` getter and the state of the `cubit` can be updated by calling `emit` with a new `state`.

![Cubit Flow](https://raw.githubusercontent.com/felangel/bloc/master/docs/assets/cubit_flow.png)

State changes in cubit begin with predefined function calls which can use the `emit` method to output new states. `onChange` is called on each state change and contains the current and next state.

#### Creating a Cubit

```dart
/// A `CounterCubit` which manages an `int` as its state.
class CounterCubit extends Cubit<int> {
  /// The initial state of the `CounterCubit` is 0.
  CounterCubit() : super(0);

  /// When increment is called, the current state
  /// of the cubit is accessed via `state` and
  /// a new `state` is emitted via `emit`.
  void increment() => emit(state + 1);
}
```

#### Using a Cubit

```dart
void main() {
  /// Create a `CounterCubit` instance.
  final cubit = CounterCubit();

  /// Access the state of the `cubit` via `state`.
  print(cubit.state); // 0

  /// Interact with the `cubit` to trigger `state` changes.
  cubit.increment();

  /// Access the new `state`.
  print(cubit.state); // 1

  /// Close the `cubit` when it is no longer needed.
  cubit.close();
}
```

#### Observing a Cubit

`onChange` can be overridden to observe state changes for a single `cubit`.

`onError` can be overridden to observe errors for a single `cubit`.

```dart
class CounterCubit extends Cubit<int> {
  CounterCubit() : super(0);

  void increment() => emit(state + 1);

  @override
  void onChange(Change<int> change) {
    super.onChange(change);
    print(change);
  }

  @override
  void onError(Object error, StackTrace stackTrace) {
    print('$error, $stackTrace');
    super.onError(error, stackTrace);
  }
}
```

`BlocObserver` can be used to observe all `cubits`.

```dart
class MyBlocObserver extends BlocObserver {
  @override
  void onCreate(Cubit cubit) {
    super.onCreate(cubit);
    print('onCreate -- cubit: ${cubit.runtimeType}');
  }

  @override
  void onChange(Cubit cubit, Change change) {
    super.onChange(cubit, change);
    print('onChange -- cubit: ${cubit.runtimeType}, change: $change');
  }

  @override
  void onError(Cubit cubit, Object error, StackTrace stackTrace) {
    print('onError -- cubit: ${cubit.runtimeType}, error: $error');
    super.onError(cubit, error, stackTrace);
  }

  @override
  void onClose(Cubit cubit) {
    super.onClose(cubit);
    print('onClose -- cubit: ${cubit.runtimeType}');
  }
}
```

```dart
void main() {
  Bloc.observer = MyBlocObserver();
  // Use cubits...
}
```

### Bloc

![Bloc Architecture](https://raw.githubusercontent.com/felangel/bloc/master/docs/assets/bloc_architecture_full.png)

A `Bloc` is a more advanced type of `Cubit` which relies on `events` to trigger `state` changes rather than functions. `Bloc` extends `Cubit` which means it has the same public API as `Cubit`. However, rather than calling a `function` on a `Bloc` and directly emitting a new `state`, `Blocs` receive `events` and convert the incoming `events` into outgoing `states`.

![Bloc Flow](https://raw.githubusercontent.com/felangel/bloc/master/docs/assets/bloc_flow.png)

State changes in bloc begin when events are added which triggers `onEvent`. The events are then funnelled through `transformEvents`. By default, `transformEvents` uses `asyncExpand` to ensure each event is processed in the order it was added but it can be overridden to manipulate the incoming event stream. `mapEventToState` is then invoked with the transformed events and is responsible for yielding states in response to the incoming events. `transitions` are then funnelled through `transformTransitions` which can be overridden to manipulation the outgoing state changes. Lastly, `onTransition` is called just before the state is updated and contains the current state, event, and next state.

#### Creating a Bloc

```dart
/// The events which `CounterBloc` will react to.
enum CounterEvent { increment }

/// A `CounterBloc` which handles converting `CounterEvent`s into `int`s.
class CounterBloc extends Bloc<CounterEvent, int> {
  /// The initial state of the `CounterBloc` is 0.
  CounterBloc() : super(0);

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    switch (event) {
      /// When a `CounterEvent.increment` event is added,
      /// the current `state` of the bloc is accessed via the `state` property
      /// and a new state is emitted via `yield`.
      case CounterEvent.increment:
        yield state + 1;
        break;
    }
  }
}
```

#### Using a Bloc

```dart
void main() async {
  /// Create a `CounterBloc` instance.
  final bloc = CounterBloc();

  /// Access the state of the `bloc` via `state`.
  print(bloc.state); // 0

  /// Interact with the `bloc` to trigger `state` changes.
  bloc.add(CounterEvent.increment);

  /// Wait for next iteration of the event-loop
  /// to ensure event has been processed.
  await Future.delayed(Duration.zero);

  /// Access the new `state`.
  print(bloc.state); // 1

  /// Close the `bloc` when it is no longer needed.
  bloc.close();
}
```

#### Observing a Bloc

Since all `Blocs` are `Cubits`, `onChange` and `onError` can be overridden in a `Bloc` as well.

In addition, `Blocs` can also override `onEvent` and `onTransition`.

`onEvent` is called any time a new `event` is added to the `Bloc`.

`onTransition` is similar to `onChange`, however, it contains the `event` which triggered the state change in addition to the `currentState` and `nextState`.

```dart
enum CounterEvent { increment }

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0);

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    switch (event) {
      case CounterEvent.increment:
        yield state + 1;
        break;
    }
  }

  @override
  void onEvent(CounterEvent event) {
    super.onEvent(event);
    print(event);
  }

  @override
  void onChange(Change<int> change) {
    super.onChange(change);
    print(change);
  }

  @override
  void onTransition(Transition<CounterEvent, int> transition) {
    super.onTransition(transition);
    print(transition);
  }

  @override
  void onError(Object error, StackTrace stackTrace) {
    print('$error, $stackTrace');
    super.onError(error, stackTrace);
  }
}
```

`BlocObserver` can be used to observe all `blocs` as well.

```dart
class MyBlocObserver extends BlocObserver {
  @override
  void onCreate(Cubit cubit) {
    super.onCreate(cubit);
    print('onCreate -- cubit: ${cubit.runtimeType}');
  }

  @override
  void onEvent(Bloc bloc, Object event) {
    super.onEvent(bloc, event);
    print('onEvent -- bloc: ${bloc.runtimeType}, event: $event');
  }

  @override
  void onChange(Cubit cubit, Change change) {
    super.onChange(cubit, change);
    print('onChange -- cubit: ${cubit.runtimeType}, change: $change');
  }

  @override
  void onTransition(Bloc bloc, Transition transition) {
    super.onTransition(bloc, transition);
    print('onTransition -- bloc: ${bloc.runtimeType}, transition: $transition');
  }

  @override
  void onError(Cubit cubit, Object error, StackTrace stackTrace) {
    print('onError -- cubit: ${cubit.runtimeType}, error: $error');
    super.onError(cubit, error, stackTrace);
  }

  @override
  void onClose(Cubit cubit) {
    super.onClose(cubit);
    print('onClose -- cubit: ${cubit.runtimeType}');
  }
}
```

```dart
void main() {
  Bloc.observer = MyBlocObserver();
  // Use blocs...
}
```

## Dart Versions

- Dart 2: >= 2.12.0-0

## Examples

- [Counter](https://github.com/felangel/Bloc/tree/master/packages/bloc/example) - an example of how to create a `CounterBloc` in a pure Dart app.

## Maintainers

- [Felix Angelov](https://github.com/felangel)

## Supporters

[<img src="https://raw.githubusercontent.com/felangel/bloc/master/docs/assets/vgv_logo.png" width="120" />](https://verygood.ventures)

## Changelog
# 7.0.0-nullsafety.0

- **BREAKING**: opt into null safety
- feat!: upgrade Dart SDK constraints to `>=2.12.0-0 <3.0.0`

# 6.1.0

- feat: add `onCreate` and `onClose` to `BlocObserver`

# 6.0.3

- docs: README updates to include flow diagrams for `Bloc` and `Cubit`.

# 6.0.2

- refactor: cubit internal memory and performance optimizations

# 6.0.1

- docs: minor documentation fixes and improvements

# 6.0.0

- **BREAKING**: do not emit current state on subscription
- **BREAKING**: `onError` in `BlocObserver` takes a `Cubit` as first parameter
- **BREAKING**: allow blocs and cubits to emit the initial state
- feat: include `cubit` and remove external dependency on [package:cubit](https://pub.dev/packages/cubit)
  - exports class `Cubit`
  - exports class `Change` (`Transition` for `Cubit`)
- feat: `onChange` added to `BlocObserver`
- refactor: apply additional lint rules
- fix: add `@visibleForTesting` to `emit` on class `Cubit`
- docs: fix inline documentation references

# 6.0.0-dev.2

- fix: add `@visibleForTesting` to `emit` on class `Cubit`

# 6.0.0-dev.1

- **BREAKING**: do not emit current state on subscription
- **BREAKING**: `onError` in `BlocObserver` takes a `Cubit` as first parameter
- **BREAKING**: allow blocs and cubits to emit the initial state
- feat: include `cubit` and remove external dependency on [package:cubit](https://pub.dev/packages/cubit)
  - exports class `Cubit`
  - exports class `Change` (`Transition` for `Cubit`)
- feat: `onChange` added to `BlocObserver`
- refactor: apply additional lint rules
- docs: fix inline documentation references

# 5.0.1

- fix: upgrade to `cubit ^0.1.2`
- docs: minor documentation updates

# 5.0.0

- **BREAKING**: remove `initialState` override in favor of providing the initial state via super ([#1304](https://github.com/felangel/bloc/issues/1304)).
- **BREAKING**: Remove `BlocSupervisor` and rename `BlocDelegate` to `BlocObserver`.
- feat: support `null` states ([#1312](https://github.com/felangel/bloc/issues/1312)).
- refactor: bloc to extend [cubit](https://pub.dev/packages/cubit) rather than `Stream`.
- feat: ignore newly added events after bloc is closed ([#1236](https://github.com/felangel/bloc/issues/1236)).
- feat: add `addError` to conform to `EventSink` interface.
- feat: mark `onError`, `onTransition`, `onEvent` as `protected`.
- docs: documentation improvements
- docs: logo updates

# 5.0.0-dev.11

- feat: add `addError` to conform to `EventSink` interface.
- feat: mark `onError`, `onTransition`, `onEvent` as `protected`.

# 5.0.0-dev.10

- docs: additional minor improvement to bloc logo alignment

# 5.0.0-dev.9

- docs: minor improvement to bloc logo alignment

# 5.0.0-dev.8

- **BREAKING**: Remove `BlocSupervisor` and rename `BlocDelegate` to `BlocObserver`.

# 5.0.0-dev.7

- Ignore newly added events after bloc is closed ([#1236](https://github.com/felangel/bloc/issues/1236)).

# 5.0.0-dev.6

- Additional documentation optimizations.

# 5.0.0-dev.5

- Optimize documentation assets for smaller viewports.

# 5.0.0-dev.4

- Update to [cubit](https://pub.dev/packages/cubit) `^0.0.13`
- Update documentation and static assets.

# 5.0.0-dev.3

- Update documentation and static assets.

# 5.0.0-dev.2

- **BREAKING**: update `initialState` to be a required positional parameter ([related issue](https://github.com/dart-lang/sdk/issues/42438)).

# 5.0.0-dev.1

- **BREAKING**: remove `initialState` override in favor of providing the initial state via super ([#1304](https://github.com/felangel/bloc/issues/1304)).
- feat: support `null` states ([#1312](https://github.com/felangel/bloc/issues/1312)).
- refactor: bloc to extend [cubit](https://pub.dev/packages/cubit) rather than `Stream`.

# 4.0.0

- Remove `rxdart` dependency ([#821](https://github.com/felangel/bloc/pull/821))
- Replace `transformStates` with `transformTransitions` ([#840](https://github.com/felangel/bloc/pull/840))
- Fix null `stackTrace` in `onError` ([#963](https://github.com/felangel/bloc/pull/963))
- Fix remove duplicate terminating state
- Add `mustCallSuper` to `onEvent`, `onTransition`, and `onError`
- Surface Unhandled Bloc Errors in Debug Mode
- Internal testing improvements

# 4.0.0-dev.4

- Surface Unhandled Bloc Errors in Debug Mode
- Internal testing improvements

# 4.0.0-dev.3

- Add `mustCallSuper` to `onEvent`, `onTransition`, and `onError`

# 4.0.0-dev.2

- Fix remove duplicate terminating state

# 4.0.0-dev.1

- Remove `rxdart` dependency ([#821](https://github.com/felangel/bloc/pull/821))
- Replace `transformStates` with `transformTransitions` ([#840](https://github.com/felangel/bloc/pull/840))
- Fix null `stackTrace` in `onError` ([#963](https://github.com/felangel/bloc/pull/963))

# 3.0.0

- Upgrade to `rxdart ^0.23.0`
- Upgrade to `Dart >= 2.6.0`

# 3.0.0-dev.1

- Upgrade to `rxdart ^0.23.0`

# 2.0.0

- Allow blocs to finish processing pending events on `close` ([#639](https://github.com/felangel/bloc/issues/639))
- Documentation Updates

# 1.0.1

- Bugfix: Exceptions thrown in `onTransition` are passed to `onError` and should not break bloc functionality ([#641](https://github.com/felangel/bloc/issues/641))
- Adhere to [effective dart](https://dart.dev/guides/language/effective-dart) ([#561](https://github.com/felangel/bloc/issues/561))
- Documentation and Example Updates

# 1.0.0

- `dispatch` and `dispose` removed
- Documentation Updates

# 0.16.1

- Minor Documentation Updates

# 0.16.0

- Bloc extends `Stream<State>` ([#558](https://github.com/felangel/bloc/issues/558))
  - `bloc.state.listen` -> `bloc.listen`
  - `bloc.currentState` -> `bloc.state`
- Bloc implements `Sink<Event>` ([#558](https://github.com/felangel/bloc/issues/558))
  - `dispatch` deprecated in favor of `add`
  - `dispose` deprecated in favor of `close`
- Documentation and Example Updates

# 0.15.0

- Removed Bloc `event` Stream ([#326](https://github.com/felangel/bloc/issues/326))
- Renamed `transform` to `transformEvents`
- Added `transformStates` ([#382](https://github.com/felangel/bloc/issues/382))

# 0.14.4

Additional Dependency and Documentation Updates.

# 0.14.3

Dependency and Documentation Updates.

# 0.14.2

- Deprecated Bloc `event` Stream ([#326](https://github.com/felangel/bloc/issues/326))
- Documentation Updates

# 0.14.1

Internal `BlocDelegate` update and Documentation Updates.

# 0.14.0

`BlocDelegate` initialization improvements and Documentation Updates.

- `BlocSupervisor().delegate = ...` is now `BlocSupervisor.delegate = ...` ([#304](https://github.com/felangel/bloc/issues/304)).

# 0.13.0

`Bloc` and `BlocDelegate` Improvements, new Features, and Documentation Updates.

- Improved `dispose` to ignore pending events ([#257](https://github.com/felangel/bloc/issues/257)).
- Exposed `event` stream on `Bloc` similar to `state` stream to expose a `Stream` of `dispatched` events ([#259](https://github.com/felangel/bloc/issues/259)).
- Update to use `rxdart` version `^0.22.0` ([#265](https://github.com/felangel/bloc/issues/265)).
- `BlocDelegate` methods include a reference to the `Bloc` instance ([#259](https://github.com/felangel/bloc/issues/259)).
- Added `onEvent` to `Bloc` and `BlocDelegate` ([#259](https://github.com/felangel/bloc/issues/259)).

# 0.12.0

Updated `transform` to enable advanced event filtering and processing and Documentation Updates.

# 0.11.2

Added `BlocDelegate` `onError` and `onTransition` mustCallSuper and Documentation Updates

# 0.11.1

Added `dispose` mustCallSuper and Documentation Updates

# 0.11.0

Update `mapEventToState` to remove unnecessary argument for `currentState`

- `Stream<S> mapEventToState(S currentState, E event)` -> `Stream<S> mapEventToState(E event)`
- Documentation Updates
- Example Updates

# 0.10.0

Updated to `rxdart ^0.21.0` and Documentation Updates

# 0.9.5

Minor Enhancements to Code Style and Documentation.

# 0.9.4

Calls to `dispatch` after `dispose` has been called trigger `onError` in the `Bloc` and `BlocDelegate`.

# 0.9.3

Restrict `rxdart` to `">=0.18.1 <0.21.0"` due to breaking changes.

# 0.9.2

Additional Minor Updates to Documentation

# 0.9.1

Minor Updates to Documentation

# 0.9.0

`Bloc` and `BlocDelegate` Error Handling

- Added `onError` to `Bloc` for local error handling.
- Added `onError` to `BlocDelegate` for global error handling.

# 0.8.4

Blocs handle exceptions thrown in `mapEventToState` and documentation updates.

# 0.8.3

Minor Internal Improvements and Documentation Updates

# 0.8.2

Additional Minor Updates to Documentation

# 0.8.1

Minor Updates to Documentation

# 0.8.0

Blocs ignore duplicate states

# 0.7.8

Additional Minor Updates to Documentation

# 0.7.7

Additional Minor Updates to Documentation

# 0.7.6

Minor Updates to Documentation

# 0.7.5

Exposed `currentState` in `Bloc`

- Updates to Documentation.

# 0.7.4

Updated `mapEventToState` parameter name

- `Stream<S> mapEventToState(S state, E event)` -> `Stream<S> mapEventToState(S currentState, E event)`
- Updates to Documentation.
- Updates to Example.

# 0.7.3

Minor Updates to Documentation

# 0.7.2

`Transition` Fix

- `Bloc` with `mapEventToState` which returns multiple states per event will now correctly report the `Transitions`.

# 0.7.1

Improvements to `Bloc` usage in pure Dart applications.

- `Bloc` state is seeded with `initialState` automatically

# 0.7.0

Added `BlocSupervisor` and `BlocDelegate`.

- `BlocSupervisor` notifies `BlocDelegate` of `Transitions`
- `BlocDelegate` exposes `onTransition` which is invoked for all `Bloc` `Transitions`.

# 0.6.0

`Transitions` and `initialState` updates.

- Added `Transition`s and `onTransition`
- Made `initialState` required

# 0.5.2

Additional minor Updates to Documentation.

# 0.5.1

Minor Updates to Documentation

# 0.5.0

Moved Flutter Widgets to flutter_bloc package

# 0.4.2

Additional minor Updates to Documentation.

# 0.4.1

Minor Updates to Documentation.

# 0.4.0

Added `BlocProvider`.

- `BlocProvider.of(context)`
- Updates to Documentation.
- Updates to Example.

# 0.3.0

Updated `mapEventToState` to take current state as an argument.

- `Stream<S> mapEventToState(E event)` -> `Stream<S> mapEventToState(S state, E event)`
- Updates to Documentation.
- Updates to Example.

# 0.2.5

Additional Minor Updates to Documentation.

# 0.2.4

Additional Minor Updates to Documentation.

# 0.2.3

Additional Minor Updates to Documentation.

# 0.2.2

Additional Minor Updates to Documentation.

# 0.2.1

Minor Updates to Documentation.

# 0.2.0

Added Support for Stream Transformation

- Includes `Stream<E> transform(Stream<E> events)`
- Updates to Documentation

# 0.1.2

Additional Minor Updates to Documentation.

# 0.1.1

Minor Updates to Documentation.

# 0.1.0

Initial Version of the library.

- Includes the ability to create a custom Bloc by extending `Bloc` class.
- Includes the ability to connect presentation layer to `Bloc` by using the `BlocBuilder` Widget.







 
