Repository navigation
Conversation
…nimation completes
|
I assume this is the same reason why I get "future already completed" when popping a route quickly after another. Are there any plans when this will be fixed/merged? |
…ion-and-animation
| widget.router.removeRoute(routeData); | ||
| widget.didPop?.call(routeData.route, null); | ||
| // ignore: deprecated_member_use | ||
| onPopPage: (route, result) { |
There was a problem hiding this comment.
Regression: imperative page removals no longer sync the router stack. With onPopPage set instead of onDidRemovePage, Flutter only calls back for Navigator.pop / maybePop / popUntil. Every other imperative removal of a page-backed route (Navigator.removeRoute, removeRouteBelow, pushReplacement, pushAndRemoveUntil, replace/replaceRouteBelow) goes through _RouteEntry.complete(..., imperativeRemoval: true), which only calls widget.onDidRemovePage (see navigator.dart handlePop/handlePush). The old code handled those through onDidRemovePage.
Scenario: app code calls Navigator.of(context).pushAndRemoveUntil(...) or removeRoute(route) on a StackedPage route. The route gets disposed, but its StackedPage stays in router._pages. removeRoute/notifyAll never run, so the URL, guards and didPop go stale. On the next notifyAll rebuild the Navigator finds a page with no entry and calls createRoute on the same StackedPage again, so the removed screen comes back. That is also the "createRoute called twice on the same page" case the completer guard in stacked_page.dart now hides silently.
| _popCompleter.complete, | ||
| ); | ||
| ..popped.then((value) { | ||
| if (!_popCompleter.isCompleted) _popCompleter.complete(value); |
There was a problem hiding this comment.
This guard hides the symptom rather than fixing it. When createRoute runs a second time on the same StackedPage (for example the page resurrected after an imperative removal, as described on route_navigator.dart), the page completer has already completed with the first route's result, usually null for a removal. Whatever the live second route pops with is then dropped silently, so a caller awaiting router.push<T>() got null early and never sees the real result. Before this change the case showed up as a StateError. Now it loses data without any signal. Consider at least an assert or debug log when the completer is already completed.
Description
This PR fixes two issues with Navigator 2.0 integration in Stacked's router:
Issues
Issue 1: Future Already Completed
Reproduction:
navigator2: truein build.yaml)Bad state: Future already completedRoot Cause:
StackedPage.canUpdate()returnstruefor matching pagesStackedPageinstance is reusedcreateRoute()is called multiple times on the same instance_popCompleterDeprecated warnings
It uses the deprecated member
onPopPage: (route, result)(lib/src/router/widgets/route_navigator.dart) as I didn't find any way to fix that usingonDidRemovePage: (page).Any feedback welcome on that!
Breaking Changes
None. The changes are internal to
StackedPageandRouteNavigatorand maintain backward compatibility.Checklist
Additional Context
These issues appear when using Navigator 2.0 with the declarative API. Navigator 1.0 is unaffected as it uses imperative navigation.
The fixes follow Flutter's own Navigator 2.0 patterns and align with the official documentation for implementing custom page-based navigation.
Related Issues
#1181