Skip to content

Instantly share code, notes, and snippets.

@jorwan
Last active October 3, 2024 18:42
Show Gist options
  • Save jorwan/79649d00b478758f07954deed2f82d32 to your computer and use it in GitHub Desktop.
Save jorwan/79649d00b478758f07954deed2f82d32 to your computer and use it in GitHub Desktop.
flutter-bloc-call-event-just-once.dart
/*
* Goal:
* Call event only on first time by bloc state
* */
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) => MultiBlocProvider(
providers: [
BlocProvider(create: (_) => PageBloc<Page1>()),
BlocProvider(create: (_) => PageBloc<Page2>()),
],
child: MaterialApp(
title: 'Example',
home: MyHomePage(),
),
);
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) => Scaffold(
body: Center(
child: Column(
children: [
const SizedBox(height: 20),
ElevatedButton(
onPressed: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => Page1())),
child: const Text('Page 1: load just once'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => Page2())),
child: const Text('Page 2: load every time'),
)
],
),
),
);
}
class Page1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
var pageBloc = context.read<PageBloc<Page1>>();
// This make data being load just once, even if widget is re-build
if (pageBloc.state is PageInitialState) {
pageBloc.add(LoadPageEvent(pageNumber: 1));
}
return Scaffold(
appBar: AppBar(title: const Text('Page 1: Load Just Once')),
body: Center(child:
BlocBuilder<PageBloc<Page1>, PageState>(builder: (context, state) {
if (state is PageLoadingState) {
return const CircularProgressIndicator();
}
return Text(state is PageLoadedState ? state.pageData : "");
})),
);
}
}
class Page2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.read<PageBloc<Page2>>().add(LoadPageEvent(pageNumber: 1));
return Scaffold(
appBar: AppBar(title: const Text('Page 2: Load Every Time')),
body: Center(child:
BlocBuilder<PageBloc<Page2>, PageState>(builder: (context, state) {
if (state is PageLoadingState) {
return const CircularProgressIndicator();
}
return Text(state is PageLoadedState ? state.pageData : "");
})),
);
}
}
/******************************
* Bloc Page Events
* ****************************/
abstract class PageEvent {}
class LoadPageEvent extends PageEvent {
final int pageNumber;
LoadPageEvent({required this.pageNumber});
}
/******************************
* Bloc Page States
* ****************************/
abstract class PageState {}
class PageInitialState extends PageState {}
class PageLoadingState extends PageState {}
class PageLoadingFailedState extends PageState {
final String error;
PageLoadingFailedState({required this.error});
}
class PageLoadedState extends PageState {
final String pageData;
PageLoadedState({required this.pageData});
}
/******************************
* Page Bloc
* ****************************/
class PageBloc<T> extends Bloc<PageEvent, PageState> {
PageBloc() : super(PageInitialState()) {
on<LoadPageEvent>((event, emit) async {
emit(PageLoadingState());
try {
String pageData = await Future.delayed(Duration(seconds: 2))
.then((_) => "...Page Data...");
emit(PageLoadedState(pageData: pageData));
} catch (e) {
emit(PageLoadingFailedState(error: e.toString()));
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment