Flutter - bloc with freezed
Flutter bloc is powerful Flutter Widgets built to work with bloc in order to build fast, reactive mobile applications.
Bloc makes it easy to separate presentation from business logic, making your code fast, easy to test, and reusable.
Bloc was designed with three core values in mind:
- Simple
Easy to understand & can be used by developers with varying skill levels. - Powerful
Help make amazing, complex applications by composing them of smaller components. - Testable
Easily test every aspect of an application so that we can iterate with confidence.
freezed enhances applications with generated ==/toString methods and sealed unions. The overriden toString is great for debugging and the overridden == ensures efficiency. Finally, sealed unions are great for enforcing hard rules over the soft conventions of traditional conditional statements such as if or switch.
In this pandemic, Let's build covid-19 app:
The purpose of this app is to fetch data from Covid Api and display those on the screen using bloc pattern and freezed.
Fundamental architecture of bloc:
You can get full source code from here.
Add below into your pubspec.yaml
dependencies:
flutter_bloc: ^4.0.0
freezed_annotation: ^0.7.1
dev_dependencies:
freezed: ^0.10.8
build_runner: ^1.9.0
covid_event.dart
import 'package:freezed_annotation/freezed_annotation.dart';
part 'covid_event.freezed.dart';
@freezed
abstract class CovidEvent with _$CovidEvent {
const factory CovidEvent.fetchSummary() = CovidSummaryEvent;
}
covid_state.dart
import 'package:covid_19/dto/covid_dto.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'covid_state.freezed.dart';
@freezed
abstract class CovidState with _$CovidState {
const factory CovidState.loading() = _CovidSummaryLoading;
const factory CovidState.content(CovidSummary summary) = _CovidSummaryContent;
const factory CovidState.error() = _CovidSummaryError;
}
covid_bloc.dart
import 'package:covid_19/bloc/covid_event.dart';
import 'package:covid_19/bloc/covid_state.dart';
import 'package:covid_19/dto/covid_dto.dart';
import 'package:covid_19/repository/repository_barrel.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class CovidBloc extends Bloc<CovidEvent, CovidState> {
CovidBloc({
this.repository,
}) : assert(repository != null);
final CovidRepository repository;
@override
CovidState get initialState => CovidState.loading();
@override
Stream<CovidState> mapEventToState(CovidEvent event) async* {
if (event is CovidSummaryEvent) {
yield CovidState.loading();
try {
final CovidSummary summary = await repository.getCovidSummary();
yield CovidState.content(summary);
} catch (_) {
yield CovidState.error();
}
}
}
}
main.dart -- snippet
BlocProvider(
create: (context) => CovidBloc(
repository: repository,
)..add(CovidSummaryEvent()),
child: HomeView(),
),
home.dart -- snippet
BlocBuilder<CovidBloc, CovidState>(
builder: (context, state) {
state.when(
loading: () {
nextView = Center(child: CircularProgressIndicator());
},
content: (summary) {
List<Country> countries = summary.countries;
countries.sort(
(a, b) => b.totalConfirmed.compareTo(a.totalConfirmed));
nextView = ListView(
...... ..... ..... ..... ....
);
},
error: () {
nextView = Center(
child: Text('Something went wrong, please try again!'));
},
);
return nextView;
You can get full source code from here.
That's it enjoy