Hi there,
I'm trying to use flutter_bloc to create a 'Goals'(basically a todo list) feature in my app. But whenever I 'add' or 'mark a goal as complete', the UI doesn't get updated, unless I restart the app. I'm not sure what I am doing wrong.
Here's my goals bloc:
class GoalsBloc extends Bloc<GoalsEvent, GoalsState> {
GoalsRepository goalsRepository;
GoalsBloc({this.goalsRepository}) : super(GoalsInitial());
@override
Stream<GoalsState> mapEventToState(
GoalsEvent event,
) async* {
if (event is FetchAllGoal) {
yield* _mapGoalsLoadedState();
}
if (event is AddGoal) {
yield* _mapGoalsAddedToState(event);
}
if (event is MarkGoalAsComplete) {
yield* _mapGoalsMarkedAsCompleteToState(event);
}
}
Stream<GoalsState> _mapGoalsLoadedState() async* {
try {
try {
List<Goal> listOfGoals = await goalsRepository.getGoals();
yield GoalsLoadedSuccess(goals: listOfGoals);
} catch (e) {
yield GoalsError();
}
} catch (e) {
print(e);
yield GoalsError();
}
}
Stream<GoalsState> _mapGoalsAddedToState(AddGoal event) async* {
try {
await goalsRepository.insertGoal(event.goal);
List<Goal> listOfGoals = await goalsRepository.getGoals();
yield GoalsLoadedSuccess(goals: listOfGoals);
} catch (e) {
yield GoalAddError();
}
}
Stream<GoalsState> _mapGoalsMarkedAsCompleteToState(
MarkGoalAsComplete event) async* {
if (state is GoalsLoadedSuccess) {
try {
await goalsRepository.updateGoal(event.newGoal);
List<Goal> listOfGoals = await goalsRepository.getGoals();
yield GoalsLoadedSuccess(goals: listOfGoals);
} catch (e) {
print(e);
yield GoalMarkAsCompleteError();
}
}
}
}
goals event:
abstract class GoalsEvent extends Equatable {
const GoalsEvent();
@override
List<Object> get props => [];
}
class AddGoal extends GoalsEvent {
final Goal goal;
AddGoal({this.goal});
}
class FetchAllGoal extends GoalsEvent {}
class FetchCurrentGoal extends GoalsEvent {}
class FetchCompletedGoals extends GoalsEvent {}
class MarkGoalAsComplete extends GoalsEvent {
final Goal newGoal;
MarkGoalAsComplete({this.newGoal});
@override
List<Object> get props => [];
}
Goal states:
abstract class GoalsState extends Equatable {
const GoalsState();
@override
List<Object> get props => [];
}
class GoalsInitial extends GoalsState {}
class GoalsLoading extends GoalsState {}
class GoalsLoadedSuccess extends GoalsState {
final List<Goal> goals;
GoalsLoadedSuccess({this.goals});
@override
List<Object> get props => [];
}
class GoalAddedSuccess extends GoalsState {
final List<Goal> goals;
const GoalAddedSuccess({this.goals});
@override
List<Object> get props => [];
}
class GoalAddError extends GoalsState {}
class GoalMarkedAsCompleteSuccess extends GoalsState {
final List<Goal> goals;
GoalMarkedAsCompleteSuccess({this.goals});
@override
List<Object> get props => [];
}
class GoalMarkAsCompleteError extends GoalsState {}
class GoalsError extends GoalsState {}
And my goals page is something like this:
Container(
child: BlocBuilder<GoalsBloc, GoalsState>(
builder: (context, state) {
if (state is GoalsLoadedSuccess) {
if (state.goals.length == 0) {
return Container();
}else{
return ListViewBuilder(
...
...
);
}
}
return Container();
},
),
),
Should I be adding extra states like "GoalAddedSuccess" and "GoalMarkedAsComplete" that does the same as "GoalLoadedSuccess" and have checks in the BlocBuilder to rebuild based on those?
Please help and thank you!
that was it!
Most helpful comment
that was it!