I have given code like below. But the accountsGroup is of empty list as the FetchAccountGroups() event is not calling while debugged.
class AccountsScreen extends StatelessWidget {
final bool fromAddEditScreen;
const AccountsScreen({
super.key,
this.fromAddEditScreen = false,
});
@override
Widget build(BuildContext context) {
return BlocProvider<AccountsBloc>(
create: (context) => getIt<AccountsBloc>()
..add(
FetchAccountGroups(),
),
child: Builder(
builder: (context) {
return Scaffold(
appBar: CommonAppBar(
showBackButton: fromAddEditScreen,
title: context.t.accounts,
leftPadding: fromAddEditScreen ? null : 18.0,
action: Padding(
padding: const EdgeInsets.only(right: 12.0),
child: IconButton(
visualDensity: VisualDensity.comfortable,
style: IconButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
backgroundColor: Colors.white,
),
onPressed: () async {
await showDialog(
context: context,
builder: (_) => AddEditAccountsDialog(
accountGroups: BlocProvider.of<AccountsBloc>(context, listen: true).getAccountGroups,
isEdit: false,
onSaveTapped: () {},
),
);
},
icon: Row(
children: [
SvgPicture.asset(
SvgAssetPaths.plusIcon,
colorFilter: const ColorFilter.mode(Colors.black, BlendMode.srcIn),
),
8.hGap,
Text(
context.t.accountScreen.addAccount,
style: context.textStyleTheme.medium14.copyWith(
color: Colors.black,
),
),
],
),
),
),
),
);
},
),
);
}
}
But if I change my code like this (assign bloc into a variable and pass to the bloc provider), it works perfectly fine. What will be the issue as I am not able to find it. Is it the issue with Flutter or with Bloc?
class AccountsScreen extends StatelessWidget {
final bool fromAddEditScreen;
const AccountsScreen({
super.key,
this.fromAddEditScreen = false,
});
@override
Widget build(BuildContext context) {
final accountsBloc = getIt<AccountsBloc>()
..add(
FetchAccountGroups(),
);
return BlocProvider<AccountsBloc>(
create: (context) => accountsBloc,
child: Builder(
builder: (context) {
return Scaffold(
appBar: CommonAppBar(
showBackButton: fromAddEditScreen,
title: context.t.accounts,
leftPadding: fromAddEditScreen ? null : 18.0,
action: Padding(
padding: const EdgeInsets.only(right: 12.0),
child: IconButton(
visualDensity: VisualDensity.comfortable,
style: IconButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
backgroundColor: Colors.white,
),
onPressed: () async {
await showDialog(
context: context,
builder: (_) => AddEditAccountsDialog(
accountGroups: BlocProvider.of<AccountsBloc>(context, listen: true).getAccountGroups,
isEdit: false,
onSaveTapped: () {},
),
);
},
icon: Row(
children: [
SvgPicture.asset(
SvgAssetPaths.plusIcon,
colorFilter: const ColorFilter.mode(Colors.black, BlendMode.srcIn),
),
8.hGap,
Text(
context.t.accountScreen.addAccount,
style: context.textStyleTheme.medium14.copyWith(
color: Colors.black,
),
),
],
),
),
),
),
);
},
),
);
}
}
I will provide the bloc event also:
List<AccountGroupsModel> _accountGroups = [];
List<AccountGroupsModel> get getAccountGroups => _accountGroups;
FutureOr<void> _onFetchAccountGroups(FetchAccountGroups event, emit) async {
final int initialItemCount = _accountGroups.length;
_accountGroups = await _accountsRepository.getAccountGroups();
if (_accountGroups.length > initialItemCount) {
emit(AddedAccountGroupsSuccessfully());
}
emit(
FetchedAccountGroups(
accountGroups: _accountGroups,
),
);
}
As I found out that the issue is as follows: While in the first case as I am using cascade to add an event and in the widget subtree I am not using any BlocBuilder or Listeners, so the bloc is managing to not even create the instance and pass to the widget tree. And while I am calling this
then only the tree is activated with bloc but that event I added at first is void and never called.
So, I solved this issue by adding
lazy=trueinside theBlocProviderwhich will anyway pass down the bloc even if it is not using anywhere.