bloc_toolkit 1.3.0-dev.2
bloc_toolkit: ^1.3.0-dev.2 copied to clipboard
A package that provides a set of tools for efficient and flexible state management using the Bloc pattern.
example/lib/main.dart
import 'dart:async';
import 'package:bloc_toolkit/bloc_toolkit.dart';
import 'package:example/animal_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:logger/logger.dart';
void main() {
final logger = Logger();
Bloc.observer = SimpleBlocObserver(logger);
runApp(const MyApp());
}
class AnimalBloc extends DataBloc<String, String> {
AnimalBloc({required AnimalRepository animalRepository})
: _animalRepository = animalRepository;
final AnimalRepository _animalRepository;
@override
FutureOr<String> loadData(DataS<String> oldState, LoadDataE<String> event) {
return _animalRepository.getAnimal(event.params!);
}
}
class SimpleBlocObserver extends BlocObserver {
SimpleBlocObserver(this._logger);
final Logger _logger;
@override
void onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
final nextState = change.nextState;
if (nextState is ErrorS) {
final error = nextState.error;
if (error is UnhandledDataException) {
_logger.f('UnhandledDataException',
error: error.error, stackTrace: error.stackTrace);
//TODO: send to analytics
}
}
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({
super.key,
});
void _showSnackBar(BuildContext context, String text) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.red,
content: Text(text),
duration: const Duration(milliseconds: 1000),
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: BlocProvider(
create: (_) => AnimalBloc(animalRepository: AnimalRepository()),
child: BlocConsumer<AnimalBloc, DataS<String>>(
listener: (context, state) {
if (state is ReloadingDataErrorS<String, String>) {
_showSnackBar(
context, 'Reloading animal error: ${state.data}');
} else if (state is LoadingDataErrorS<String, String>) {
_showSnackBar(
context, 'Loading animal error: ${state.error}');
}
},
builder: (context, state) {
if (state.isLoading) {
return const Text('Loading animal...');
}
if (state.isUnloaded) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Animal not loaded'),
ElevatedButton(
onPressed: () {
context
.read<AnimalBloc>()
.add(const LoadDataE(params: 'some args'));
},
child: const Text('Load Animal'),
),
],
);
}
if (state.isLoaded) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(state.data!),
ElevatedButton(
onPressed: () {
context
.read<AnimalBloc>()
.add(const ReloadDataE(params: 'some args'));
},
child: const Text('Reload Animal'),
),
],
);
}
if (state.isLoading) {
return const Text('Loading animal...');
}
return const SizedBox();
},
))),
);
}
}