Skip to content

Instantly share code, notes, and snippets.

@manojeeva
Last active May 27, 2023 23:01
Show Gist options
  • Save manojeeva/f3d70387a19bbbfa4506d839cd163885 to your computer and use it in GitHub Desktop.
Save manojeeva/f3d70387a19bbbfa4506d839cd163885 to your computer and use it in GitHub Desktop.
GetX Manage Multiple Dialog
import 'package:get/get.dart';
import 'package:flutter/material.dart';
class OverLayLoader {
OverLayLoader._privateConstructor();
static final OverLayLoader find = OverLayLoader._privateConstructor();
Route _dialogRoute;
void show([String text = "Loading Please Wait"]) {
Get.dialog(
LoaderWidget(
text: text,
contextCallback: _storeRoute,
removeContext: () => _dialogRoute = null,
),
barrierDismissible: false,
routeSettings: RouteSettings(name: "Dialog loader"),
);
}
void hide() => _removeRoute();
void _storeRoute(BuildContext context) {
_dialogRoute = ModalRoute.of(context);
}
void _removeRoute() {
if (_dialogRoute.isNull) return;
Get.removeRoute(_dialogRoute);
_dialogRoute = null;
}
}
class LoaderWidget extends StatelessWidget {
final String text;
final ValueChanged<BuildContext> contextCallback;
final VoidCallback removeContext;
const LoaderWidget({
Key key,
this.text,
this.contextCallback,
this.removeContext,
}) : super(key: key);
@override
Widget build(BuildContext context) {
contextCallback(context);
return WillPopScope(
onWillPop: () async {
removeContext();
return true;
},
child: Center(
child: Column(
children: [
CircularProgressIndicator(),
Text(text),
],
),
),
);
}
}
class APIClient {
Future<void> getExceptionFromAPI() async {
try {
await Future.delayed(Duration(seconds: 3));
throw Error();
} catch (e) {
Get.snackbar("Exception", "Something worng");
}
}
}
class ControllerOne extends GetxController {
final apiClient = APIClient();
void runAPINewFlow() async {
OverLayLoader.find.show();
await apiClient.getExceptionFromAPI();
OverLayLoader.find.hide();
}
void runAPIOldFlow() async {
Get.dialog(
LoaderWidget(
text: "old Loading will not hide, press back",
contextCallback: (_) {},
removeContext: () {},
),
barrierDismissible: false,
);
await apiClient.getExceptionFromAPI();
//exception will not show. Loader Will not hide.
//cause we simply goback one route (which hides the snackbar)
Get.back();
}
}
class PageOne extends StatelessWidget {
final ControllerOne controller;
PageOne() : controller = Get.put(ControllerOne());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
color: Colors.yellow,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
RaisedButton(
onPressed: controller.runAPIOldFlow,
child: Text("Old Flow"),
),
RaisedButton(
onPressed: controller.runAPINewFlow,
child: Text("New Flow"),
),
],
),
)),
);
}
}
@manojeeva
Copy link
Author

This very simple use-case.
Let's say we have to call API and don't worry about the exception shown to the user.
Usecase 1
Controller ->Show Loader -> Call API -> Exceiption (show toast)->Hide Loader -> Toast is hidden (not loader)
This use-case seems to be not working with normal dialog.
When you want to hide loader, you need to call Get.back() right?
After Exception Toast is shown. Now in the controller, we try to hide the loader. It doesn't hide it instead it closes the snack bar.
To overcome this we now manage the dialog route in a variable and remove that specific dialog.
So, Now.
Controller ->Show Loader -> Call API -> Exceiption (show toast)->Hide Loader (specific Loader) ->Toast still showing.
This can be used with different use cases where you show multiple dialogs and chose the specific one.
Please also check the original workflow done by @roipeker here

Let me know if you need a full working code. Will prepare it for you with a regular one and a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment