I have an app where I'm emitting budgetLoaded() in several events. I have noticed that if I don't emit a different state with my budgetLoading even the app doesn't seem to respond to the change.
import 'package:bloc/bloc.dart';
import 'package:budget_app/model/budget.dart';
import 'package:budget_app/model/budget_repository.dart';
import 'package:equatable/equatable.dart';
part 'budget_event.dart';
part 'budget_state.dart';
class BudgetBloc extends Bloc<BudgetEvent, BudgetState> {
final BudgetRepository budgetRepository;
BudgetBloc({required this.budgetRepository}) : super(BudgetInitial()) {
on<AppStarted>((event, emit) async {
emit(BudgetLoading());
if (await budgetRepository.hasBudget()) {
emit(BudgetLoaded(budget: budgetRepository.budget));
} else {
emit(BudgetLoaded(budget: budgetRepository.budget));
}
});
on<Withdraw>((event, emit) {
budgetRepository.budget.withdraw(event.amount);
emit(BudgetLoaded(budget: budgetRepository.budget));
});
on<Deposit>((event, emit) {
emit(BudgetLoading());
budgetRepository.budget.deposit(event.amount);
emit(new BudgetLoaded(budget: budgetRepository.budget));
});
}
}
This is an issue with the deposit event. This code works.
import 'package:bloc/bloc.dart';
import 'package:budget_app/model/budget.dart';
import 'package:budget_app/model/budget_repository.dart';
import 'package:equatable/equatable.dart';
part 'budget_event.dart';
part 'budget_state.dart';
class BudgetBloc extends Bloc<BudgetEvent, BudgetState> {
final BudgetRepository budgetRepository;
BudgetBloc({required this.budgetRepository}) : super(BudgetInitial()) {
on<AppStarted>((event, emit) async {
emit(BudgetLoading());
if (await budgetRepository.hasBudget()) {
emit(BudgetLoaded(budget: budgetRepository.budget));
} else {
emit(BudgetLoaded(budget: budgetRepository.budget));
}
});
on<Withdraw>((event, emit) {
budgetRepository.budget.withdraw(event.amount);
emit(BudgetLoaded(budget: budgetRepository.budget));
});
on<Deposit>((event, emit) {
budgetRepository.budget.deposit(event.amount);
emit(new BudgetLoaded(budget: budgetRepository.budget));
});
}
}
This code does not work the state that is emitted is correct, I have unit tests to test this and I've done debugging.
This is the main page, the BlocProvider is in the Main file above the Material App so it should be global.
import 'package:budget_app/bloc/budget_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class WalletScreen extends StatefulWidget {
const WalletScreen({Key? key}) : super(key: key);
@override
State<WalletScreen> createState() => _WalletScreenState();
}
class _WalletScreenState extends State<WalletScreen> {
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => onPressed(context),
child: Icon(Icons.add),
),
body: BlocBuilder<BudgetBloc, BudgetState>(
bloc: BlocProvider.of<BudgetBloc>(context),
builder: (context, state) {
if (state is BudgetLoaded) {
var budget = state.budget;
return SafeArea(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
child: Center(
child: Column(
children: [
Text(
'Current Balance:',
style: TextStyle(
color: Colors.white, fontSize: 25),
),
Text(
'${budget.numberFormatted}',
style: TextStyle(
color: Colors.green, fontSize: 50),
),
],
),
),
color: Colors.blueGrey,
),
),
),
],
),
),
);
} else {
return CircularProgressIndicator();
}
},
),
);
}
onPressed(BuildContext context) {
var budgetBloc = BlocProvider.of<BudgetBloc>(context);
budgetBloc.add(Deposit(100.00));
}
}
It's not a huge issue I just want to understand why it doesn't work.
EVENT
part of 'budget_bloc.dart';
abstract class BudgetEvent extends Equatable {
const BudgetEvent();
@override
List<Object> get props => [];
}
class AppStarted extends BudgetEvent {}
class Withdraw extends BudgetEvent {
final double amount;
const Withdraw(this.amount);
}
class Deposit extends BudgetEvent {
final double amount;
const Deposit(this.amount);
}
STATE
part of 'budget_bloc.dart';
abstract class BudgetState extends Equatable {
const BudgetState();
@override
List<Object> get props => [];
}
class BudgetInitial extends BudgetState {}
class BudgetLoading extends BudgetState {}
class BudgetLoaded extends BudgetState {
final Budget budget;
BudgetLoaded({required this.budget});
}