I wanted to make a timer based on the Internet cubit. when Internet Disconnected State is emitted timer should be reset. But after reset(when Internet Disconnect state emitted) it is emitting increment timer state again.
Home Cubit (timer cubit)
class HomeCubit extends Cubit<HomeState> {
HomeCubit() : super(HomeState.initial());
void increment() {
Timer.periodic(const Duration(seconds: 1), (timer) {
emit(state.copyWith(counter: state.counter + 1));
});
}
void reset() {
emit(
state.copyWith(counter: 0),
);
}
}
Home State (timer state)
class HomeState extends Equatable {
final int counter;
const HomeState({
required this.counter,
});
factory HomeState.initial() {
return const HomeState(counter: 0);
}
HomeState copyWith({
int? counter,
}) {
return HomeState(
counter: counter ?? this.counter,
);
}
@override
List<Object?> get props => [counter];
}
Internet Cubit
class InternetCubit extends Cubit<InternetState> {
final Connectivity connectivity;
late StreamSubscription internetStreamSubscription;
InternetCubit({required this.connectivity}) : super(InternetInitial()) {
monitorInternet();
}
void monitorInternet() {
internetStreamSubscription = connectivity.onConnectivityChanged.listen((connectivityResult) {
if (connectivityResult == ConnectivityResult.wifi) {
emit(const InternetConnected(connectionType: ConnectionType.wifi));
} else if (connectivityResult == ConnectivityResult.mobile) {
emit(const InternetConnected(connectionType: ConnectionType.mobileData));
} else if (connectivityResult == ConnectivityResult.none) {
emit(InternetDisconnected());
}
});
}
@override
Future<void> close() {
internetStreamSubscription.cancel();
return super.close();
}
}
Internet State
enum ConnectionType { wifi, mobileData }
abstract class InternetState extends Equatable {
const InternetState();
@override
List<Object> get props => [];
}
class InternetInitial extends InternetState {}
class InternetConnected extends InternetState {
final ConnectionType connectionType;
const InternetConnected({required this.connectionType});
@override
List<Object> get props => [connectionType];
}
class InternetDisconnected extends InternetState {}
Homepage view
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return BlocListener<InternetCubit, InternetState>(
listener: (context, state) {
if (state is InternetConnected) {
context.read<HomeCubit>().increment();
} else if (state is InternetDisconnected) {
context.read<HomeCubit>().reset();
}
},
child: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('You have been connected to the Internet for the past'),
Text(context.watch<HomeCubit>().state.counter.toString()),
],
),
),
),
);
}
}
I tried Cubit stream subscribe too. but why it is re-emitting old state again? why timer not staying in 0 or reset state?
If I understand you correctly you want the timer to stay 0 when you call reset()
in HomeCubit().
Try this:
class HomeCubit extends Cubit<HomeState> {
HomeCubit() : super(HomeState.initial());
Timer? timer;
void increment() {
timer ??= Timer.periodic(const Duration(seconds: 1), (timer) {
emit(state.copyWith(counter: state.counter + 1));
});
}
void reset() {
timer?.cancel();
timer = null;
emit(
state.copyWith(counter: 0),
);
}
}