0

I am trying to execute a function after a dialog is dismissed/popped. I read this article How to run code after showDialog is dismissed in Flutter? and tried to do it as recommended but it wouldn't work for me.

This is how I call my dialog:

Future<void> onDeleteEventData(BuildContext context) async {
    final title = context.messages.settings.offline.deleteEventData;
    final subTitle = context.messages.settings.offline.deleteEventDataDesc;
    final res = await showDeleteDialog(context,
      title: title,
      subTitle: subTitle);
    if (res == true){
      context.read<EventDownloadTileController>().deleteEventRelatedData();
    }
  }

The showDeleteDialog function just calls a custom Dialog which is basically just the Flutter Dialog with some style changes.

Future<bool?> showDeleteDialog(BuildContext context,
    {required String title, String? subTitle}) async {
  return await showDialog(
      context: context,
      builder: (_) => DeleteDialog(title: title,subTitle: subTitle,)
  );
}

In the dialog I press on a button and do this:

onPressed: () => Navigator.of(context).pop(true),

So looking at the first function I wait for my res which evaluates to true. At this point I thought the dialog should be popped. But it is not.

The problem is this call:

context.read().deleteEventRelatedData();

Because when I replace this call with e.g. Future.delayed(duration(seconds:5)); the dialog pops right away as expected.

This is the function:

  Future<void> deleteEventRelatedData() async {
    _ticketLoader.stop();
    _ticketStorage.deleteScanTicketsForEvent(event.eventId);
    _eventStorage.deleteEventPermissions(event.eventId);
    _eventStorage.deleteEventData(event.eventId);
    _ticketStorage.deleteCachedTicketsForEvent(event.eventId);
    _ticketStorage.deleteCachedUnknownTicketsForEvent(event.eventId);
    _ticketLoader.updateLastSync(null);
    _ticketLoader.reset();
    checkLocalStatus();
  }

A function with some async and synchronous functions. The execution takes up to 3 seconds which is the time it takes to dismiss/pop my dialog. But I want to pop the dialog right away and let it work in the back. What could my function possibly do for this behavior?

Thanks in advance

Yuki
  • 255
  • 1
  • 2
  • 9

1 Answers1

0

The dialog window isn't going to disappear until the app can manage to do a rebuild. If your function call takes a while, it could be hogging the main thread until it's complete, disallowing other code (including widget code) from running.

Try wrapping your function call in a microtask so it doesn't run until the next available task window which will give the app time to clean up the dialog window:

await Future.microtask(deleteEventRelatedData);

It's also worth mentioning the body of the deleteEventRelatedData is marked as async but it never awaits anything. That means all of the synchronous calls can happen in a sequence that wasn't intended and the asynchronous calls won't get executed until a later time and in no guaranteed order.

Abion47
  • 22,211
  • 4
  • 65
  • 88
  • Thank you for your answer. But the dialog is still not closing until the function is executed. Yes I marked the deleteEventRelatedData as async because I tried earlier to put await in front of the async functions. It is usually not a async function. Do you have any other suggestions regarding my problem? – Yuki Feb 08 '23 at 07:45
  • @Valentin What could be happening is that the dialog is triggered to disappear, but in the immediate next frame as it starts to disappear, your function runs which, again, blocks the main thread. To test this theory, replace `Future.microtask(deleteEventRelatedData)` with `Future.delayed(Duration(seconds: 2), deleteEventRelatedData)`. If that fixes the problem, your issue is that your function is trying to do too much at once, and your best course of action is to either break it up or move it to an isolate. – Abion47 Feb 08 '23 at 16:22