I need to fetch data initially when my app starts (flutter framework, cubit as state management). I thought about different approaches, and would like your feedback on which design is good:
a) In the Start Screen: Calling a method "collectDataFromRepository" from the cubit, when BlocProvider is installed.
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => ManageCostCubit(fakeLocalRepository)..getAllCost(),
child: MaterialApp(
routes: {
b) In a second screen: Inside initState, by calling a method in the cubit class and consuming the return value? Imho receiving a return value from a cubit method seems to be contrary to the architecture. The architecture suggests receiving state objects which hold the data.
@override
void initState() {
super.initState();
myList = context.read<ManageCostCubit>().getAllCost();
}
c) In a second screen: Inside initState, by calling void method in the cubit class and accessing the state object? But "state" doesn't seem to be available there, i get red underlines with this:
if (state is Success) {
costList = state.costs;
}
However, I never saw a initState method in examples that were crowded with several state-depending codes. Because I can not be sure that accessing remote data is successful.
d) Ignoring Cubit at all and accessing the repository directly from the UI, also in the initState-Method in the second Screen. Actually accessing the repo directly would be the simplest, but since I am facing different connection situations, I think using Cubit is right.
Technically it would be ideal to fetch data closest as possible to where it's being used, Unless it's big data, then it would be a good UX to fetch it where the user most likely won't notice. Allocating memory to data that might not be used is not a good design.
For example: An app has a settings page with multiple nested pages with huge data. If the settings is not the main function of the app, there's no need to fetch all the data every time, Rather load initial data, then once the page is visited, load next pages' data while the user is viewing and probably navigating. It might save time & memory. Even if it's milliseconds, it may contribute to an overall good experience and performance.
Your options a) & b) give the same results. If
getAllCost()
function is being used here to simply fetch the data & is not needed to be maintained, See FutureBuilder instead.However, the proper way to use
flutter_bloc
is to emit states with the value. Have a function that fetches your data and while waiting for results, emit a loading state then if succeeded or failed emit other states, each for success and failed.Example:
c) You need a listener such as
BlocBuilder
to listen to sate changes. If you need to read the state atinitState
once, You may useBlocProvider
like so:d) If both methods achieve the same results, The method with the scalability, maintainability and lesser code would contribute to a better developer experience.