Cubit State Return Always A Null Value
i am learning flutter-bloc with freezed, i am trying to retrieve a data from sqflite. i have a achieved that without bloc pattern, it worked fine. but when i use bloc to do so the return value is always null!.
This Button when is clicked it is supposed to retrieve data:
BlocBuilder<DisplayNoteCubit, DisplayNoteState>(
builder: (context, state) {
return MaterialButton(
onPressed: () async {
print( '\n print all Data \n ${state.maybeMap(orElse: () {}, getData: (g) => g.notes)}');
},
child: const Text("Click Me"),
);
},
),
bloc code is:
final DBHelper _db=DBHelper.instance;
class DisplayNoteCubit extends Cubit<DisplayNoteState> {
DisplayNoteCubit() : super(const DisplayNoteState.initial());
void getData() {
state.maybeMap(
orElse: () {},
getData: (getData) async{
emit(getData.copyWith(notes:await _db.getAllNotesFormDB()));
});
}
}
state code is:
@freezed
abstract class DisplayNoteState with _$DisplayNoteState {
const factory DisplayNoteState.initial() = Initial;
const factory DisplayNoteState.getData({required List<Map<String, dynamic>> notes}) = GetData;
}
Answer
When using Cubit, your state lifecycle looks like this:
- You call a method on Cubit;
- Cubit processes the method and emits a new state;
- Your UI subscribes to the state and re-renders accordingly.
Now, you need to fix several aspects in your code:
Step 1.BlocBuilder
is used only when you need to subscribe to state changes and render UI based on the current state. In your case, you only want to execute the method with your button, so BlocBuilder
is not needed in this case.
Change this:
BlocBuilder<DisplayNoteCubit, DisplayNoteState>(
builder: (context, state) {
return MaterialButton(
onPressed: () async {
print( '\n print all Data \n ${state.maybeMap(orElse: () {}, getData: (g) => g.notes)}');
},
child: const Text("Click Me"),
);
},
),
to this:
return MaterialButton(
onPressed: () async {
context.read<DisplayNoteCubit>().getData(); // Triggers getData() method on Cubit
},
child: const Text("Click Me"),
);
Step 2. Retrieve data and emit state change.
Change this:
final DBHelper _db=DBHelper.instance;
class DisplayNoteCubit extends Cubit<DisplayNoteState> {
DisplayNoteCubit() : super(const DisplayNoteState.initial());
void getData() {
state.maybeMap(
orElse: () {},
getData: (getData) async{
emit(getData.copyWith(notes:await _db.getAllNotesFormDB()));
});
}
}
to this:
final DBHelper _db=DBHelper.instance;
class DisplayNoteCubit extends Cubit<DisplayNoteState> {
DisplayNoteCubit() : super(const DisplayNoteState.initial());
Future<void> getData() async {
final notes = await _db.getAllNotesFormDB();
emit(DisplayNoteState.getData(notes: notes)); // Emits state with retrieved notes
}
}
Step 3. Render your UI. Now, you should use the BlocBuilder
method to render your state. You could use state.maybeMap()
here as you tried before. For example:
BlocBuilder<DisplayNoteCubit, DisplayNoteState>(
builder: (context, state) {
return state.maybeMap(
getData: (getDataState) { ... },
orElse: () { ... },
);
},
),
Related Questions
- → How do you create a 12 or 24 mnemonics code for multiple cryptocurrencies (ETH, BTC and so on..)
- → Flutter: input text field don't work properly in a simple example..... where am I wrong?
- → Can I customize the code formatting of Dart code in Atom?
- → Is it possible to develop iOS apps with Flutter on a Linux virtual machine?
- → Display SnackBar in Flutter
- → JSON ObjectMapper in Flutter
- → Material flutter app source code
- → TabBarSelection No such method error
- → How do I set the animation color of a LinearProgressIndicator?
- → Add different routes/screens to Flutter app
- → Is there a way to get the size of an existing widget?
- → How to share a file using flutter
- → Is there an easy way to find particular text built from RichText in a Flutter test?