-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Return value when pop #3368
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
Return value when pop #3368
Conversation
@chunhtai Here it is |
@@ -17,6 +17,7 @@ dependencies: | |||
go_router: | |||
path: .. | |||
logging: ^1.0.0 | |||
package_info_plus_web: ^2.0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be removed?
packages/go_router/CHANGELOG.md
Outdated
@@ -3,6 +3,10 @@ | |||
- Updates compileSdkVersion to 33. | |||
- Updates example app to iOS 11. | |||
|
|||
## 6.3.0 | |||
|
|||
- Support for returning values on pop. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Support for returning values on pop. | |
- Supports for returning values on pop. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please move the item under ## NEXT to be under 6.3.0 as well
packages/go_router/doc/navigation.md
Outdated
```dart | ||
onTap: () { | ||
final bool? result = await context.push<bool>('/page2'); | ||
WidgetsBinding.instance.addPostFrameCallback((_) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why a post frame callback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was before context.mounted was implemented, and using context after the value was returned lead to some dirty context problems, but we can take it out
@@ -113,6 +116,7 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList> | |||
final _NavigatorStateIterator iterator = _createNavigatorStateIterator(); | |||
while (iterator.moveNext()) { | |||
if (iterator.current.canPop()) { | |||
iterator.matchList.last.completer?.complete(result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of exposing the completer directly, can you add a method in RouteMatch something like didComplete()? and let ImperativeRouteMatch to override the method to call complete on the completer
@@ -27,6 +30,7 @@ class RouteMatch { | |||
required String parentSubloc, // e.g. /family/f2 | |||
required Map<String, String> pathParameters, | |||
required Object? extra, | |||
Completer<dynamic>? completer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use method this property should be in ImerativeRouteMatch, and instead of dynamic, it should use generic type T
@@ -91,10 +92,12 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList> | |||
error: matches.last.error, | |||
pageKey: pageKey, | |||
matches: matches, | |||
completer: completer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not let ImperativeRouteMatch to create the completer itself.
@@ -278,6 +282,7 @@ class ImperativeRouteMatch extends RouteMatch { | |||
required super.error, | |||
required super.pageKey, | |||
required this.matches, | |||
super.completer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somewhere in the doc should mention about the completer and future and what it meant.
also, please remove the todo for me. Thanks in advance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Since this is not really a breaking change, so you don't need to write a breaking change doc. Consider moving the snippet in the doc into the example folder |
let me know if there's another change to make |
packages/go_router/CHANGELOG.md
Outdated
## 6.3.0 | ||
|
||
- Supports for returning values on pop. | ||
|
||
## NEXT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant the ##Next section should be merged in 6.3.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## Next
meant whoever publish the next version will need to publish the changes in##NEXT
as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AHHHHH, got it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems not address yet?
@@ -61,6 +63,18 @@ class RouteMatch { | |||
throw MatcherError('Unexpected route type: $route', restLoc); | |||
} | |||
|
|||
/// Completes the promise returned by [GoRouter.push]. | |||
void complete([T? value]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the entire completer should be move to ImperativeRouteMatch. This can just be a empty implementation for subclass override
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also maybe change this to didComplete. it is a special keyword in the framework, that has specific meaning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -61,6 +63,18 @@ class RouteMatch { | |||
throw MatcherError('Unexpected route type: $route', restLoc); | |||
} | |||
|
|||
/// Completes the promise returned by [GoRouter.push]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should document what the purpose of this method
/// ```dart | ||
/// context.pop(true); | ||
/// ``` | ||
void complete([dynamic value]) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chunhtai what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why optional? I think it can be Object? value
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant this method should be call didComplete
.
void didComplete(Object? value) {}
@@ -61,6 +61,29 @@ class RouteMatch { | |||
throw MatcherError('Unexpected route type: $route', restLoc); | |||
} | |||
|
|||
/// Completes the promise returned by [GoRouter.push], allowing comunication |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe:
Called when the corresponding [Route] associated with this route match is completed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/// Completes the promise returned by [GoRouter.push], allowing comunication | ||
/// between pages. | ||
/// | ||
/// If the promise has already been completed, this method does nothing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
promise is not a keyword in dart. I think you meant future
. Eitherway, this is implementation detail, we should focus on when/why this method is called.
/// ```dart | ||
/// context.pop(true); | ||
/// ``` | ||
void complete([dynamic value]) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why optional? I think it can be Object? value
.
|
||
/// The future of the [RouteMatch] completer. When the future completes, this | ||
/// will return the value passed to [complete]. | ||
Future<T?> get future => _completer.future; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be private
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is we need to return this completer future in the push function, if we make it private we cannot return it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can access private method as long as the class is in the same file, so it should be fine
/// ```dart | ||
/// context.pop(true); | ||
/// ``` | ||
void complete([dynamic value]) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant this method should be call didComplete
.
void didComplete(Object? value) {}
@@ -104,7 +104,7 @@ class GoRouteInformationParser extends RouteInformationParser<RouteMatchList> { | |||
} | |||
if (configuration.matches.last is ImperativeRouteMatch) { | |||
configuration = | |||
(configuration.matches.last as ImperativeRouteMatch).matches; | |||
(configuration.matches.last as ImperativeRouteMatch<dynamic>).matches; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be Object?
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should avoid using dynamic as much as possible unless you are handling json.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just some nits and change log
|
||
/// The future of the [RouteMatch] completer. When the future completes, this | ||
/// will return the value passed to [complete]. | ||
Future<T?> get future => _completer.future; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can access private method as long as the class is in the same file, so it should be fine
_completer.complete(value as T?); | ||
} | ||
|
||
/// The future of the [RouteMatch] completer. When the future completes, this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// The future of the [RouteMatch] completer. When the future completes, this | |
/// The future of the [RouteMatch] completer. | |
/// | |
/// When the future completes, this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't know about private methods being accessed if in the same file, really cool!
packages/go_router/CHANGELOG.md
Outdated
## 6.3.0 | ||
|
||
- Supports for returning values on pop. | ||
|
||
## NEXT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems not address yet?
and the analyzer is not happy |
@chunhtai fixed the change log, almost forgot. |
Waiting for resolving this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
It looks like there is some conflict, can you rebase off the latest main? |
auto label is removed for flutter/packages, pr: 3368, Failed to merge pr#: 3368 with Pull request could not be merged: Pull Request is not mergeable. |
Done |
@@ -1,5 +1,6 @@ | |||
## 6.3.0 | |||
|
|||
- Supports returning values on pop. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please publish a new version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to 6.5.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the conflict is back :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I'm resolving them rn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything is a mess hahahaha, I'll rebase it to main and made the implementation again 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chunhtai now there shouldn't be any more conflicts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
grande naza! |
Niceeeeeeeeee |
Return value when pop
In this PR I'm modifying the push and pushNamed by making them return a Future<T?>, and using completers to make the users able to return an wait values from within pages.
Fixes flutter/flutter#99663.
Fixes flutter/flutter#107217
Fixes flutter/flutter#100969
This PR will not conflict with older versions of go_router when updated.
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style.///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.