I have a bloc responsible for viewing and editing existing notes and adding a new note (which is basically just editing empty note)
So based on a state - ViewDetailsState or EditDetailsState I wanna show cards with text or text fields for editing. However state is not getting updated when I call the event.
My code is the following:
States:
class EditDetailsState extends DetailsState {
final Note note;
const EditDetailsState(this.note);
@override
List<Object> get props => [note];
}
class AddNoteState extends DetailsState {
final Note note;
const AddNoteState(this.note);
@override
List<Object> get props => [note];
}
Bloc:
@override
Stream<DetailsState> mapEventToState(
DetailsEvent event,
) async* {
if(event is GetNoteDetails){
yield* _mapGetNoteDetailsToState(event);
}else if(event is NewNoteMode){
yield* _mapNewNoteModeToState(event);
}else if(state is EditMode){
yield* _mapEditModeToState(event);
}
}
Stream<DetailsState> _mapGetNoteDetailsToState(GetNoteDetails event) async*{
Note note = await _notesRepository.getNoteById(event.noteId);
yield ViewDetailsState(note);
}
Stream<DetailsState> _mapNewNoteModeToState(NewNoteMode event) async*{
yield EditDetailsState(new Note(''));
}
Stream<DetailsState> _mapEditModeToState(EditMode event) async*{
yield EditDetailsState(event.note);
}
My View:
Widget build(BuildContext context){
return BlocListener<DetailsBloc, DetailsState>(
listener: (context, state){
},
child: BlocBuilder<DetailsBloc, DetailsState>(
builder: (context, state){
if(state is InitialDetailsState && widget.noteId != ''){
_detailsBloc.add(GetNoteDetails(widget.noteId));
}
if(state is InitialDetailsState && widget.noteId == ''){
_detailsBloc.add(NewNoteMode());
}
if(state is ViewDetailsState){
_note = state.note;
return new Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () => Navigator.of(context).pop(),
),
actions: <Widget>[
_editAction(state),
_deleteAction(_note, context),
],
backgroundColor: ColorsPalette.greenGrass,
),
body: Container(
padding: EdgeInsets.only(bottom: 65.0),
child:
Column(children: <Widget>[
_titleViewCard(),
_textViewCard()
])
)
);
}
if(state is EditDetailsState){
_note = state.note;
_titleController = new TextEditingController(text: _note.title);
_textController = new TextEditingController(text: _note.text);
return new Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () => Navigator.of(context).pop(),
),
actions: <Widget>[
_saveAction(state),
_deleteAction(_note, context),
],
backgroundColor: ColorsPalette.greenGrass,
),
body: Container(
padding: EdgeInsets.only(bottom: 65.0),
child:
Column(children: <Widget>[
_titleCard(),
_textCard()
])
)
);
}
return Container();
}
),
);
}
So when I call _editAction() event _detailsBloc.add(EditMode(state.note)); is triggered
However view is not updated with text fields.
Can someone please take a look and see what am I missing?
Hi @YanaKrivitskaya ✌
Could you share a repo link?
@YanaKrivitskaya thanks for sharing. Unfortunately your project depends on firebase so without a google-services.json
file I cannot run it locally. Could you maybe create a decoupled sample reproducing the issues you're trying to overcome ?
@RollyPeres Correct, sorry
here is a test project:
https://github.com/YanaKrivitskaya/bloc_test
When you click on a note in main menu and then click on edit sign - I expect state to be updated and text fields appear
@YanaKrivitskaya I've opened a PR with the fix and some small improvements: https://github.com/YanaKrivitskaya/bloc_test/pull/1
I've also left you a couple of comments and todos to further help you.
Hope it gets you on the right track! ✌
@RollyPeres Thank you!
The error with state instead of event is soooo epic fail 😅
Most helpful comment
@YanaKrivitskaya I've opened a PR with the fix and some small improvements: https://github.com/YanaKrivitskaya/bloc_test/pull/1
I've also left you a couple of comments and todos to further help you.
Hope it gets you on the right track! ✌