I use bloc 8.0.1
and http ^0.13.4
.
When you run the application, only the WeatherInitial()
status appears on the screen. I can't see other states. debugPrint("debug3");
I can't see the line of code in console. The try catch doesn't go inside the line of code. Can you find out what the problem is?
BLOC
class WeatherBloc extends Bloc<WeatherEvent, WeatherState> {
final WeatherRepository repository = locator<WeatherRepository>();
WeatherBloc() : super(WeatherInitial()) {
on<WeatherEvent>((event, emit) async {
if (event is FetchWeatherEvent) {
WeatherLoadingState();
try {
final Weather? weather = await repository.getWeather(event.cityName);
WeatherLoadedState(weather: weather!);
debugPrint("debug3");
} catch (_) {
WeatherErrorState();
}
}
});
}
}
EVENT
abstract class WeatherEvent extends Equatable {
const WeatherEvent();
@override
List<Object> get props => [];
}
class FetchWeatherEvent extends WeatherEvent {
final String cityName;
const FetchWeatherEvent({required this.cityName});
}
State
abstract class WeatherState extends Equatable {
const WeatherState();
@override
List<Object> get props => [];
}
class WeatherInitial extends WeatherState {}
class WeatherLoadingState extends WeatherState {}
class WeatherLoadedState extends WeatherState {
final Weather weather;
const WeatherLoadedState({required this.weather});
}
class WeatherErrorState extends WeatherState {}
Body
class WeatherApp extends StatelessWidget {
String? selectedCity;
@override
Widget build(BuildContext context) {
final _weatherBloc = BlocProvider.of<WeatherBloc>(context);
return Scaffold(
appBar: AppBar(
title: const Text("WeatherApp"),
actions: [
IconButton(
onPressed: () async {
selectedCity = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const CityChoose(),
),
);
if (selectedCity != null) {
_weatherBloc.add(FetchWeatherEvent(cityName:
selectedCity!));
}
},
icon: const Icon(Icons.search),
),
],
),
body: Center(
child: BlocBuilder(
bloc: _weatherBloc,
builder: (context, WeatherState state) {
if (state is WeatherInitial) {
return const Center(
child: Text("Select City"),
);
}
if (state is WeatherLoadingState) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (state is WeatherLoadedState) {
final weather = state.weather;
debugPrint(weather.title);
return ListView(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: LocationWidget(
selectedCity: weather.title,
)),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Center(child: LastUpdateWidget()),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Center(child: WeatherImageWiddget()),
),
const Padding(
padding: EdgeInsets.all(16.0),
child: Center(child: TemperatureCondition()),
),
],
);
} else {
return const Center(
child: Text("Error"),
);
}
},
),
),
CodePudding user response:
You need to use emit
to emit a state in the Bloc
. emit
is declared in the closure of on<T>
.
emit(WeatherLoadedState(weather: weather!));
emit(WeatherErrorState());