I need help with a pad that doesn't seem to be firing the fetch method I'm calling an API with.
The error I am getting is:
══╡ EXCEPTION CAUGHT BY PROVIDER ╞═══════════════════════════════
The following _CastError was thrown:
type 'Null' is not a subtype of type 'HomeBloc' in type cast
I am attaching code for the pad, class methods, main and widgets.
part 'home_event.dart';
part 'home_state.dart';
class HomeBloc extends Bloc<HomeEvent, HomeState> {
final PlayerService _playerService;
HomeBloc(this._playerService) : super(HomeLoadingState()) {
on<LoadApiEvent>((event, emit) async {
final player = await _playerService.fetchHomeData();
emit(HomeLoadedState(player.playerId, player.playerName,
player.playerPoints, player.playerEmail, player.playerAlbums));
});
}
}
part of 'home_bloc.dart';
abstract class HomeEvent extends Equatable {
const HomeEvent();
}
class LoadApiEvent extends HomeEvent {
@override
List<Object?> get props => [];
}
part of 'home_bloc.dart';
abstract class HomeState extends Equatable {
const HomeState();
}
class HomeLoadingState extends HomeState {
@override
List<Object> get props => [];
}
class HomeLoadedState extends HomeState {
final int playerId;
final String playerName;
final String playerPoints;
final String playerEmail;
final List<PlayerAlbum> playerAlbums;
const HomeLoadedState(this.playerId, this.playerName, this.playerPoints,
this.playerEmail, this.playerAlbums);
@override
List<Object> get props =>
[playerId, playerName, playerPoints, playerEmail, playerAlbums];
}
Attached main code and home widget, where the provider is used:
void main() {
runApp(const MyApp());
}
return MaterialApp(
home: MultiRepositoryProvider(
providers: [
RepositoryProvider(
create: (context) => PlayerService(),
),
],
child: HomePageView(),
));
This is the home page widget that draws the content of the pad:
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => HomeBloc(
RepositoryProvider.of<PlayerService>(context),
)..add(LoadApiEvent()),
child: Scaffold(
backgroundColor: Colors.blue.shade800,
appBar: const CustomAppBar(title: "LaminApp"),
bottomNavigationBar: CircularBottomNavigation(
tabItems,
selectedCallback: (int? selectedPos) {
print("clicked on $selectedPos");
},
selectedPos: selectedPos,
barBackgroundColor: Colors.white,
),
body: SingleChildScrollView(
child: Column(
children: [
const SizedBox(
height: 30,
),
BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
if (state is HomeLoadedState) {
return Text(
state.playerName,
style: CustomTextStyle.cardItemTextStyle,
);
} else {
return Container();
}
},
),
Problem:
The Flutter_Bloc package uses the Bloc package, which in turn uses the Provider package, and the provider uses the context (BuildContext) to propagate classes throughout the app. It's like a dependency injector.
What is the problem, then?
That you can't use provider, therefore, Bloc instances can't either, in the same context in which you inject it. In your case:
Solution:
Refresh the context. How?
It simply extracts the BlocBuilder part into its own widget, that way creating another stateless widget, with its own build method, which is already a different context, and will be able to access the injected bloc.
Another option is to use the Builder widget
This widget offers a context parameter that you can use instead of the context of the build method, said context would be refreshed.