New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent dialog from appearing on top of another dialog #40
Comments
This code snippet should resolve most of your issues. class MiddleWare {
static MiddleWare _instance;
factory MiddleWare() {
if (_instance == null) _instance = MiddleWare._();
return _instance;
}
MiddleWare._();
static Routing _routing;
static Routing get routing => _routing;
static observer(Routing rt) {
_routing = rt;
}
}
class Foo {
openDialog() {
if(!MiddleWare.routing.isDialog){
// or if(MiddleWare.routing.isDialog) Get.back(); to close dialog and open other
Get.dialog(YourDialogClass())
}
}
}
Middleware.rounting will give you everything you need. Current route, if you have an open dialog, if you have an open snackbar, if you have an open bottomsheet, if the open route is "x" or "y", and anyway, you can use this approach. |
Looks like whatever sets the routing.isDialog to true is not fast enough, because I'm still getting dual dialogs when 2 api connections fail at the same time. Any other ideas? |
|
I'm trying to reproduce the problem, but I'm not getting it. |
For testing purposes only, does adding await before Get.dialog change anything? |
It's multiple requests to an api that expires an auth token. This is my request method:
|
Well, I did a lot of tests, including sending the context by parameter to test if this behavior is a Get problem, and I found out that this is the default behavior of the framework, and that you must implement your own logic to prevent this from happening. I didn't close this question because I intend to help you with that. Are you sure your error code is not making a double call? Try this static Future<dynamic> post(String endpoint, {Object params}) async {
Map<String, String> headers = {"Content-Type": "application/json"};
bool isDialogOpen = false; // ADD THIS
LoginResultsDTO loginResults = CurrentUser().loginResults;
if (loginResults?.oAuth?.accessToken != null &&
loginResults?.oAuth?.tokenType != null) {
headers['Authorization'] =
loginResults.oAuth.tokenType + ' ' + loginResults.oAuth.accessToken;
}
final body = params == null ? null : jsonEncode(params);
print('\n${URLS.BASE_URL}$endpoint\n${params ?? ''}');
final response = await http.post('${URLS.BASE_URL}$endpoint',
headers: headers, body: body);
if (response.statusCode == 200) {
if (response.body.length == 0) return true;
return json.decode(response.body);
} else {
if (response.body != null) {
ErrorDTO error = ErrorDTO.fromJson(json.decode(response.body));
if (error.raw != null) {
switch (error.code) {
case ServerError.authorizationExpired:
print('Try to refresh token');
if (loginResults != null) {
OAuthDTO refreshOAuth = await AuthenticationService.refresh(
loginResults.oAuth?.refreshToken,
loginResults.user?.userID);
var refreshLoginResults =
LoginResultsDTO.withOAuth(refreshOAuth, loginResults);
CurrentUser().setLoginResults(refreshLoginResults);
return await Api.post(endpoint, params: params);
}
throw ServerException('No login results', error);
break;
case ServerError.authorizationFailed:
case ServerError.invalidAuthorizationToken:
CurrentUser().setLoginResults(null);
if (!isDialogOpen) { // CHANGE THIS
isDialogOpen = true;
print('error dialog');
Get.defaultDialog(
title: 'Error',
content: Text(error.code.description),
confirm: FlatButton(
child: Text('OK'),
onPressed: () {
Get.until(Routes.Login, (Route route) {
return route.isFirst;
});
},
),
);
}
//throw ServerException(error.code.description, error);
break;
case ServerError.Unknown:
print(error.raw);
throw ServerException(error.raw, error);
break;
}
}
} else {
print(response.toString());
throw Exception('Failed');
}
}
} |
Ok, here is a fully reproducible code:
Your addition with the |
Thanks for opening this issue, after the reproduction code I was able to trace the root of the problem, and GetObserver is improved now. Can you reproduce the problem using version 1.16.1-dev? |
Nice!! It seems to be working on the test snippet. I'll implement it in the app now and let you know how it goes |
Flawless! Thanks!! |
New API added import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:rpm/middleware.dart';
class TestScreen extends StatelessWidget {
void login() {
getTestError();
getTestError();
}
Future<dynamic> getTestError() async {
final response =
await http.get('http://www.mocky.io/v2/5e97d4673000007900b6e08c');
if (response.statusCode == 200) {
return response.body;
} else {
if (!Get.isDialogOpen) { // Now you can made this
print('error dialog');
await Get.defaultDialog(
title: 'Error',
content: Text('There was an error'),
confirm: FlatButton(
child: Text('OK'),
onPressed: () {
Get.back();
},
),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: FlatButton(
child: Text('Test'),
onPressed: login,
),
),
),
);
}
} |
Great! I verified it. Works like a charm |
I'm currently displaying a dialog when my API throws an error.
The problem I'm running into is that I'm making mulitple calls at the same time, and sometimes I get multiple errors, so I end up with getting multiple dialogs open at the same time.
Is there a way to prevent this? Or is there a way to figure out if there is currently a dialog open? So I can check for that before displaying the dialog.
The text was updated successfully, but these errors were encountered: