1

I am facing a use case I don't know the proper way to deal with.

Please see here the simple application I have made: https://dartpad.dev/?id=5a00b315613990d8c3ead6e26bc2df4c

This tries to simulate the typical scenario where you have a record list page with data recovered from a data base, click on one of the records, make some changes and click the "Save" button to go back to the list page and see those changes updated.

If I use context.push(), I can see the changes correctly because it returns a Future so I can wait until context.pop() is executed in the detail screen and then I run getDataFromDataBase() to refresh the data from the database.

The problem I have with using context.push() is the URL is not updated when I run this for the web.

If I use context.go() instead then the URL is properly updated but since this returns void I cannot properly wait to update the records after context.pop()

I feel I am missing something because this must be a very typical scenario. Let's see if you can point me in the right direction:

  1. Is it the expected behaviour that context.push() doesn't modify the URL?
  2. In case I use context.go() instead (which by the way seems to be the recommended way to navigate according to the official documentation since imperative navigation can cause some problems: https://pub.dev/documentation/go_router/latest/topics/Navigation-topic.html). What's the proper way to manage this scenario? How to update data after context.pop()

Thank you.

rocotocloc
  • 418
  • 6
  • 19

1 Answers1

1

ATM, I'm looking for an answer to your first question myself so I can't answer that.

As for the second one, you can work around it by creating a Promise, and pass a function fulfilling that promise into your editing dialog.

Something like this:

class MyPage extends StatelessWidget {
  const MyPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      // ...
      TextButton(
        onPressed: () async {
          final promise = Completer<bool>();
          context.go('/somePath', extra: promise.complete);
          final editResult = await promise.future;
          // ....
        },
        child: Text('Edit'),
      )
    ]);
  }
}

You can then pick the function up from the extra-field in your route, pass it into your dialog and call it when editing is done.

tjarvstrand
  • 836
  • 9
  • 20
  • Thanks @tjarvstrand. Anyway I ended up moving to auto_route package as I found it more convenient for my case. This one updates the URL properly with its core functions. As per the second point, I found it easy to do it through observers to trigger certain operations on push/pop: https://pub.dev/packages/auto_route#navigation-observers – rocotocloc Aug 11 '23 at 10:45
  • FWIW I found this old issue, so I don't think it's intended behavior: https://github.com/flutter/flutter/issues/115962. I created a new one: https://github.com/flutter/flutter/issues/132430. With regards to auto_router, it seems more convenient, but I don't really trust it. It's unbelievably complex for what it does, code quality is so-so, and documentation about what actually goes on under the hood is non-existent. – tjarvstrand Aug 12 '23 at 08:53
  • Thanks @tjarvstrand. So it seems it's related to this option: https://pub.dev/documentation/go_router/latest/go_router/GoRouter/optionURLReflectsImperativeAPIs.html but anyways it's not recommended to set it to true, imperative navigation is strongly discouraged: https://pub.dev/documentation/go_router/latest/topics/Navigation-topic.html. We'll try to find a workaround and follow the recommended guidelines. Thanks again. – rocotocloc Aug 28 '23 at 07:55