I want to create a GlobalMessageUtils
class that would open a material snackbar or dialog without having to pass the build context. The idea is that whenever there's any error (no network, bad request, etc) I am able to pop open a snackbar and relay the message to the user.Is there a concept of global context
?
I was playing with the idea of making my GlobalMessageUtils
class a singleton that takes in a build context
and instantiate it at the MaterialApp
level, but I haven't gotten this to work. Any body have any ideas? Is this even a good pattern in flutter? If not, how do you guys deal with error handling at a global level?
then you can simply call the Get. snackbar() to show the snackbar where you want it to be displayed. You can use this package when you don't have the context too. Save this answer.
The ElevatedButton is a child widget placed on the return Center . Then, we use the ScaffoldMessenger class to display the SnackBar. Clicking on the button will show the SnackBar with the following message: “Hi, I am a SnackBar!”
Using the BLOC pattern and Rxdart, I created a UiErrorUtils
class
class UiErrorUtils {
// opens snackbar
void openSnackBar(BuildContext context, String message) async {
await Scaffold.of(context).showSnackBar(
SnackBar(
content: Text(message),
),
);
}
// subscribes to stream that triggers open snackbar
void subscribeToSnackBarStream(BuildContext context, PublishSubject<String> stream){
stream.listen((String message){
openSnackBar(context, message);
});
}
}
In your StatefulWidget, you can use the context provided in the initState
hook:
class WidgetThatUsesUIErrorUtils extends StatefulWidget {
final UiErrorUtils uiErrorUtils;
final Bloc bloc;
WidgetThatUsesUIErrorUtils({this.uiErrorUtils, this.bloc});
WidgetThatUsesUIErrorUtils createState() => WidgetThatUsesUIErrorUtilsState(
uiErrorUtils: uiErrorUtils,
bloc: bloc,
);
}
class WidgetThatUsesUIErrorUtilsState extends State<WidgetThatUsesUIErrorUtils> {
final Bloc _bloc;
final UiErrorUtils _uiErrorUtils;
WidgetThatUsesUIErrorUtilsState({Bloc bloc, UiErrorUtils uiErrorUtils})
: _bloc = bloc ?? Bloc(),
_uiErrorUtils = uiErrorUtils ?? UiErrorUtils();
@override
void initState() {
super.initState();
// Subscribe to UI feedback streams from provided _bloc
_uiErrorUtils.subscribeToSnackBarStream(context, _bloc.snackBarSubject);
}
}
BLOC
class Bloc extends BlocBase {
// UI Feedback Subjects
final PublishSubject<String> snackBarSubject = PublishSubject<String>();
// some function that gets data from network
Future<bool> getDataRequest() async {
try {
// get request code here
} catch(error) {
this.snackBarSubject.add(error);
}
}
@override
void dispose() {
snackBarSubject?.close();
}
}
Now your widget has subscribed to the bloc's snackBarStream.
So in your bloc whenever a request fails you can add the message to the snackBarStream and since your widget has subscribed via UiErrorUtils
the snackbar will trigger with the message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With