Yuki
Yuki

Reputation: 325

Why is my function preventing the dialog dismiss/pop in Flutter?

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

Upvotes: 0

Views: 165

Answers (1)

Abion47
Abion47

Reputation: 24661

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.

Upvotes: 0

Related Questions