Reputation: 487
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;
}
Upvotes: 0
Views: 1556
Reputation: 5333
When using Cubit, your state lifecycle looks like this:
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: () { ... },
);
},
),
Upvotes: 2