Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deprecate: BlocOverrides API #3470

Closed
felangel opened this issue Aug 2, 2022 · 3 comments
Closed

deprecate: BlocOverrides API #3470

felangel opened this issue Aug 2, 2022 · 3 comments
Assignees
Labels
deprecation A public API is being deprecated pkg:bloc This issue is related to the bloc package pkg:hydrated_bloc This issue is related to the hydrated_bloc package

Comments

@felangel
Copy link
Owner

felangel commented Aug 2, 2022

Overview

The BlocOverrides API was introduced in v8.0.0 in an attempt to support scoping bloc-specific configurations such as BlocObserver, EventTransformer, and HydratedStorage. In pure Dart applications, the changes worked well; however, in Flutter applications the new API caused more problems than it solved.

The BlocOverrides API was inspired by similar APIs in Flutter/Dart:

Problems

While it wasn't the primary reason for these changes, the BlocOverrides API introduced additional complexity for developers. In addition to increasing the amount of nesting and lines of code needed to achieve the same effect, the BlocOverrides API required developers to have a solid understanding of Zones in Dart. Zones are not a beginner-friendly concept and failure to understand how Zones work could lead to the introduction of bugs (such as uninitialized observers, transformers, storage instances).

For example, many developers would have something like:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  BlocOverrides.runZoned(...);
}

The above code, while appearing harmless, can actually lead to many difficult to track bugs. Whatever zone WidgetsFlutterBinding.ensureInitialized is initially called from will be the zone in which gesture events are handled (e.g. onTap, onPressed callbacks) due to GestureBinding.initInstances. This is just one of many issues caused by using zoneValues.

In addition, Flutter does many things behind the scenes which involve forking/manipulating Zones (especially when running tests) which can lead to unexpected behaviors (and in many cases behaviors that are outside the developer's control -- see issues below).

Due to the use of the runZoned, the transition to the BlocOverrides API led to the discovery of several bugs/limitations in Flutter (specifically around Widget and Integration Tests):

which affected many developers using the bloc library:

Decision

After many discussions with various members of the community (including folks from the Dart/Flutter teams), we've decided to deprecate the BlocOverrides API and reintroduce the previous APIs in order to provide a safe, beginner friendly API, eliminate the need to worry about the above issues. When using Zones, technically there's nothing stopping another package from overriding the Zone values provided or even creating a brand new Zone which does not inherit the previous zone specifications. By moving back to the previous API, we eliminate these potential pit-falls and end up with a safer, simpler API.

Next Steps

The BlocOverrides and HydratedBlocOverrides APIs will be deprecated, the previous Bloc.observer, Bloc.transformer, and HydratedBloc.storage APIs will be restored, and the deprecated APIs will be removed in the next major release.

Migration

Currently, in order to specify a custom BlocObserver or EventTransformer we use the BlocOverrides.runZoned API:

Before

void main() {
  BlocOverrides.runZoned(
    () {
      // Application code...
    },
    blocObserver: MyBlocObserver(),
    eventTransformer: myEventTransformer(),
  );
}

After these changes, you will be able to use the previous APIs (from v7.x.x) to specify a custom BlocObserver, EventTransformer, or HydratedStorage instance.

After

void main() {
  Bloc.observer = MyBlocObserver();
  Bloc.transformer = myEventTransformer(),
  // Application code...
}
@felangel felangel added deprecation A public API is being deprecated pkg:bloc This issue is related to the bloc package pkg:hydrated_bloc This issue is related to the hydrated_bloc package labels Aug 2, 2022
@felangel felangel self-assigned this Aug 2, 2022
@purplenoodlesoop
Copy link
Contributor

Hi @felangel!

That's a good call, BlocOverrides did raise a lot of questions. I maintain an ecosystem-compatible BLoC alternative that uses the old API, and I have encountered similar complaints from users of my package.

To avoid breaking changes, I've implemented a system that can use both Zone injection and plain static variables – maybe you could use it as a reference to do something similar.

@felangel
Copy link
Owner Author

felangel commented Aug 6, 2022

The BlocOverrides API has been deprecated in bloc v8.1.0.

@felangel felangel closed this as completed Aug 6, 2022
@bartekpacia
Copy link

Thank you very much @felangel!

polilluminato added a commit to polilluminato/wassword-flutter that referenced this issue Nov 2, 2022
On Bloc v8.1.0 runZoned became deprecated as described here

felangel/bloc#3470
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deprecation A public API is being deprecated pkg:bloc This issue is related to the bloc package pkg:hydrated_bloc This issue is related to the hydrated_bloc package
Projects
None yet
Development

No branches or pull requests

3 participants