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

feat(evented_bloc): A new package for Blocs and Cubits with the ability to fire events... #4026

Closed
jovazcode opened this issue Dec 12, 2023 · 1 comment
Labels
duplicate This issue or pull request already exists

Comments

@jovazcode
Copy link

Description

The lack of capacity to fire events from Blocs and Cubits makes us having to create and manage what we usually call "temporary states", which is a kind of a "hack" (cause an event is an event, like 'FetchErrorEvent' for example while the state of a Bloc is, at least for me, another usage).

Desired Solution

I usually implement in my projects this kind of Blocs and Cubits. Example:

class CounterCubit extends EventedCubit<int, CounterEvent> {
  CounterCubit() : super(0);

  void increment() {
    emit(state + 1);
    fireEvent(const CounterEvent.incremented()); // <- Here the Cubit fires an "IncrementedEvent"
  }

  void decrement() {
    emit(state - 1);
    fireEvent(const CounterEvent.decremented()); // <- Here the Cubit fires a "DecrementedEvent"
  }
}

My implementation of EventedCubit, is as follow:

/// {@template evented_cubit}
/// Specialized [Bloc] which handles initializing the [Cubit]
/// stream of events.
/// {@endtemplate}
abstract class EventedCubit<State, Event> extends Cubit<State>
    with EventedMixin<Event, State> {
  /// {@macro evented_cubit}
  EventedCubit(super.state) {
    initEvented();
  }
}

I use a mixin on "BlocBase<State>" so that I can put there  all the implementation code (cause I cannot modify your "bloc" stacks!!)

For the app I created a simple Widget which I call "BlocEventListener" (100% similar to your BlocListener):

  @override
  Widget build(BuildContext context) {
    return BlocEventListener<CounterCubit, CounterEvent>(
      listenWhen: (bloc, event) => true,
      listener: (context, cubit, event) {
        /// Handle the event
      },
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: () => context.read<CounterCubit>().increment(),
            child: const Icon(Icons.add),
          ),
          hSpace60,
          ElevatedButton(
            onPressed: () => context.read<CounterCubit>().decrement(),
            child: const Icon(Icons.remove),
          ),
        ],
      ),
    );
  }

Additional Context

What I totally avoid in my apps, is the use of "temporary states" and hacks with "noOps", as shown in the following article:

https://itnext.io/flutter-blocs-at-scale-1-the-state-machine-fce5f086d7b9

@felangel
Copy link
Owner

Closing this as a duplicate of #4008

@felangel felangel added the duplicate This issue or pull request already exists label Dec 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants