Skip to content
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

Make go() asynchronous #108764

Open
johnpryan opened this issue Aug 1, 2022 · 4 comments
Open

Make go() asynchronous #108764

johnpryan opened this issue Aug 1, 2022 · 4 comments
Labels
c: proposal A detailed proposal for a change to Flutter p: go_router The go_router package P3 Issues that are less important to the Flutter project package flutter/packages repository. See also p: labels. team-go_router Owned by Go Router team triaged-go_router Triaged by Go Router team

Comments

@johnpryan
Copy link
Contributor

johnpryan commented Aug 1, 2022

If we are making redirection asynchronous (#105808) we should also make go() and goNamed() asynchronous. We should also make push and pushNamed asynchronous, but it's not specified how redirection is handled for push methods.

Context: #105808 (comment)

@johnpryan johnpryan added the p: go_router The go_router package label Aug 1, 2022
@danagbemava-nc danagbemava-nc added p: first party package flutter/packages repository. See also p: labels. c: proposal A detailed proposal for a change to Flutter labels Aug 2, 2022
@stuartmorgan stuartmorgan added the P3 Issues that are less important to the Flutter project label Aug 2, 2022
@NazarenoCavazzon
Copy link
Contributor

Hi Guys, I made a PR for solving other issue that might as well solve this one, you can take a look flutter/packages#2416. The only change that I would need to make in order to make it work for you guys is making the go method also asynchronous.

@cedvdb
Copy link
Contributor

cedvdb commented Aug 9, 2022

I'll reiterate here as there was some discussion as whether or not to make it asynchronous in another issue:

  • there are valid use cases where you have to wait for the navigation to complete to do something (eg reset something in a non UI layer, not needing context).
  • the other solution provided is just a trick to hide the asynchronous nature, and is just indirection on top of an operation that is async behind the curtains which doesn't strike me as a good idea / api.
  • the fact that context is inaccessible makes sens, documentation should prevent missuses.
  • it makes testing easier

Not doing this will result in lots of annoyance and needless indirection in my experience (I also have a router library and this has proven to be a must have).

@Lzyct
Copy link

Lzyct commented Oct 21, 2022

Any update about this issue?

@cmz-one
Copy link

cmz-one commented Dec 29, 2022

This is an ugly method until the official has not been modified.

final GoRouter router = GoRouter(
  observers: [FutureNavigatorObserver()],
  routes: ...,
);

class FutureNavigatorObserver extends NavigatorObserver {
  @override
  void didPop(Route route, Route? previousRoute) async {
    super.didPop(route, previousRoute);
    FutureGoRouter.didPop(route.settings.name, await route.popped);
  }
}

class FutureGoRouter {
  static final List<_FutureGoItem> _asyncList = [];

  /// [path] Add new parameter ,it must equal to [route.settings.name]
  static FutureOr<T?> go<T>(String location, String path, {Object? extra}) {
    router.go(location, extra: extra);
    Completer<T?> completer = Completer();
    _asyncList.add(_FutureGoItem(path, completer));
    return completer.future;
  }

  /// the [routeSettingName] must equal to [path]
  static void didPop(String? routeSettingName, dynamic popped) {
    _FutureGoItem? asyncItem;
    for (int i = 0; i < _asyncList.length; i++) {
      if (_asyncList[i].path == routeSettingName) {
        asyncItem = _asyncList[i];
      }
    }
    if (asyncItem != null) {
      _asyncList.remove(asyncItem);
      asyncItem.completer.complete(popped);
    }
  }
}

class _FutureGoItem {
  final String path;
  final Completer completer;

  _FutureGoItem(this.path, this.completer);
}

How to use?

final result = await FutureGoRouter.go<int>('/test?a=1&b=2','test');
...
router.pop(999);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: proposal A detailed proposal for a change to Flutter p: go_router The go_router package P3 Issues that are less important to the Flutter project package flutter/packages repository. See also p: labels. team-go_router Owned by Go Router team triaged-go_router Triaged by Go Router team
Projects
No open projects
Status: No status
Development

No branches or pull requests

8 participants