Home > Software design >  The event I am dispatching is not called in the Bloc
The event I am dispatching is not called in the Bloc

Time:08-12

I am new to the Bloc Pattern in Flutter. I started using it in combination with the freezed package. But my event is not called from within the Bloc (or not dispatched at all)

Following is what I have,

State

part of 'language_selection_bloc.dart';

@freezed
class LanguageSelectionState with _$LanguageSelectionState {
  const factory LanguageSelectionState.initial(Language language) = Initial;
}

Event

part of 'language_selection_bloc.dart';

@freezed
class LanguageSelectionEvent with _$LanguageSelectionEvent {
  const factory LanguageSelectionEvent.languageSelected(Language language) = LanguageSelected;
}

Bloc

part 'language_selection_event.dart';
part 'language_selection_state.dart';

part 'language_selection_bloc.freezed.dart';

class LanguageSelectionBloc extends Bloc<LanguageSelectionEvent, LanguageSelectionState> {
  LanguageSelectionBloc() : super(const Initial(Language.english)) {
    on<LanguageSelected>((event, emit) {
      state.copyWith(language: event.language);
    });
  }
}

Language Model

enum Language {
  english,
  sinhala,
  tamil;

  String get value {
    switch (this) {
      case Language.english:
        return 'English';

      case Language.sinhala:
        return 'Sinhala';

      case Language.tamil:
        return 'Tamil';
    }
  }
}

How I provide the Bloc

class LanguageSelectionPage extends StatelessWidget {
  const LanguageSelectionPage({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => LanguageSelectionBloc(),
      child: const LanguageSelectionView(),
    );
  }
}

How I dispatch the event

      BlocBuilder<LanguageSelectionBloc, LanguageSelectionState>(
        buildWhen: ( previous, current) => previous.language != current.language,
        builder: (context, state) => Flexible(
          child: ListTile(
            leading: Radio<Language>(
              value: language,
              groupValue: state.language,
              onChanged: (value) => context.read<LanguageSelectionBloc>().add(LanguageSelected(value!)),
            ),
            trailing: Padding(
              // Adjust this for spacing between the radio and the text
              padding: const EdgeInsets.only(right: 110),
              child: Text(
                language.value,
                textAlign: TextAlign.left,
                style: const TextStyle(
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
          ),
        ),
      )

** No matter how hard I try, the event I am dispatching using the line context.read<LanguageSelectionBloc>().add(LanguageSelected(value!)) is not being called inside the bloc.

I tried for hours and hours and could not find a solution.

Can someone please help?

CodePudding user response:

Have you rebuilt the application? Hot reload doesn't work you need to restart it if you do something in the bloc-files.

If you add a print('something') before emit in your onLanguageSelected does it print anything at all?

I can't really see anything wrong by just looking at your code. You could try to lift up your BlocProvider to the top of the widget tree.

Add a BlocProvider / MultiBlocProvider to your runApp function in your main file with your app as child, something like this:

runApp(
    MultiBlocProvider(
        providers: [
            BlocProvider(
                create: (context) => LanguageSelectionBloc(),
            )
        ]
    ),
    child: const YourApp(),
)

CodePudding user response:

Couldnt able to find any issues in your code. May be can you try this instead of context.read? Although both are similar , Provider.of has backwards compatibility.

   Provider.of<LanguageSelectionBloc>(context, listen: false).add(LanguageSelected(value!));
  • Related