So I am a native iOS developer who switched to flutter. Perhaps the problem I face currently with the bloc package has an easy fix but I have spent hours researching for a potential fix but have failed. This simple app i am building is simply a notes app. The issue i face is updating the UI based on a state change. Basically when i add a new item, the item gets added to the state but doesn't reflect in the Gridview.builder until i hot reload the app I threw all my frustrations on chatgpt just for it to keep on throwing gibberish responses.
My state
// ignore_for_file: public_member_api_docs, sort_constructors_first
part of 'note_bloc.dart';
abstract class NoteState extends Equatable {
const NoteState();
@override
List<Object?> get props => [];
}
class NoteInitial extends NoteState {}
//! App Initial State
class Notes extends NoteState {
final List<NoteModel> noteList;
const Notes(this.noteList);
@override
List<Object?> get props => [noteList];
}
My Events
// ignore_for_file: public_member_api_docs, sort_constructors_first
part of 'note_bloc.dart';
abstract class NoteEvent extends Equatable {
const NoteEvent();
@override
List<Object> get props => [];
}
class DeletedNote extends NoteEvent {
final int id;
const DeletedNote({
required this.id,
});
}
class SavedNote extends NoteEvent {
final String message;
final DateTime time;
const SavedNote({
required this.message,
required this.time,
});
}
class EdittedNote extends NoteEvent {
final String message;
final DateTime time;
const EdittedNote({
required this.message,
required this.time,
});
}
My Bloc
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:notebook/data/model/note_model.dart';
part 'note_event.dart';
part 'note_state.dart';
class NoteBloc extends Bloc<NoteEvent, NoteState> {
NoteBloc() : super(const Notes([])) {
final List<NoteModel> noteModel = [];
on<SavedNote>((event, emit) async {
noteModel.add(NoteModel(noteModel.length + 1, event.time, event.message));
await Future.delayed(const Duration(seconds: 1));
emit(Notes(noteModel));
});
}
}
//! Since this project is a test project i packed everything in one file
UI
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'blocs/bloc/note_bloc.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const BlocTestScreen());
}
class BlocTestScreen extends StatelessWidget {
const BlocTestScreen({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => NoteBloc(),
child: PlatformApp(
material: (context, platform) =>
MaterialAppData(theme: ThemeData(useMaterial3: true)),
home: const HomeScreen(),
),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return PlatformScaffold(
appBar: PlatformAppBar(
backgroundColor: Colors.amber,
title: PlatformText('NoteBook'),
trailingActions: [
PlatformIconButton(
onPressed: () {
showPlatformDialog(
context: context,
builder: (context) {
return PlatformAlertDialog(
actions: [
Padding(
padding: const EdgeInsets.all(20.0),
child: PlatformElevatedButton(
child: const Text('Save'),
onPressed: () {
BlocProvider.of<NoteBloc>(context).add(SavedNote(
message: 'message', time: DateTime.now()));
Navigator.pop(context);
},
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: PlatformElevatedButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.pop(context);
},
),
),
],
material: (context, platform) =>
MaterialAlertDialogData(content: const TextField()),
cupertino: (context, platform) =>
CupertinoAlertDialogData(
content: const CupertinoTextField()),
);
});
},
cupertino: (context, platform) =>
CupertinoIconButtonData(icon: const Icon(CupertinoIcons.add)),
material: (context, platform) =>
MaterialIconButtonData(icon: const Icon(Icons.add)),
)
],
),
body: BlocBuilder<NoteBloc, NoteState>(
builder: (context, state) {
if (state is Notes) {
return Center(
child: GridView.builder(
itemCount: state.noteList.length,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (context, index) {
final note = state.noteList[index];
print(state.noteList.length);
return Card(
child: ListTile(
title: Text(note.time.toString()),
subtitle: Text(note.message),
),
);
}));
} else {
return Center(
child: PlatformCircularProgressIndicator(),
);
}
},
),
);
}
}
I tried everything chat gpt told me including the equatable Package but it only increased my stress levels even further. I expect to see individual card elements added to the gridview on the saved button tapped but it kept on showing only one card until hot-reloaded.
update your note_bloc :
class NoteBloc extends Bloc<NoteEvent, NoteState> {
NoteBloc() : super(const Notes([])) {
final List<NoteModel> noteModel = [];
on<SavedNote>((event, emit) async {
noteModel.add(NoteModel(
id: noteModel.length + 1, time: event.time, message: event.message));
await Future.delayed(const Duration(seconds: 1));
emit(Notes(noteModel.toList()));
});
}
}
here video link : enter link description here