I am having a hard time understanding how to deal with states in some specific situations with Flutter.
For example, say I need a page where the click of a button fetches data from an API. Such a request could take time or any kind of problems could happen. For this reason, I would probably use the BLoC pattern to properly inform the user while the request goes through various "states" such as loading, done, failed and so on.
Now, say I have a page that uses a Timer to periodically (every 1sec) update a Text Widget with the new elapsed time value of a Stopwatch. A timer needs to be properly stopped (timer.cancel()) once it is not used anymore. For this reason, I would use a Stateful Widget and stop the timer directly in the dispose state.
However, what should one do when they have a page which both :
- Fetches data from API and/or other services which require correctly handling states.
- Uses a
Timeror anything (streams ?) that requires proper canceling/closing/disposing of...
Currently, I have a page which makes API calls and also holds such a Timer. The page is dealt with the BLoC pattern and the presence of the Timer already makes the whole thing a little tedious. Indeed, creating a BLoC "just" to update a Timer feels a little bit like overkill.
But now, I am facing a problem. If the user doesn't go through the page the "regular" way and decides to use the "back button" of his phone: I never get to cancel the Timer. This, in turn, will throw the following error: Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
Indeed, even after having pop() to the previous page, the Timer is still running and trying to complete its every 1sec duty :
Timer.periodic(
const Duration(seconds: 1),
(Timer t) {
context.read<TimerBloc>().add(const Update());
},
);
}
Could someone please explain to me how such "specific" situations should be handled? There must be something, a tiny little concept that I am not totally understand, and I can feel it is slowing me down sometimes.
Thank you very much in advance for any help.
First off, this is opinionated.
Even though you've described a lot, it is a bit tricky to follow your cases and how you've (specifically) implemented it. But I'll give it a shot at describing things to consider.
There are several ways to handle this. I'll try to answer your questions.
The result if you build it: