Skip to content

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

Merged
merged 23 commits into from
Mar 23, 2023

Conversation

NazarenoCavazzon
Copy link
Contributor

@NazarenoCavazzon NazarenoCavazzon commented Mar 3, 2023

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

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.
  • I updated CHANGELOG.md to add a description of the change, following repository CHANGELOG style.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@NazarenoCavazzon
Copy link
Contributor Author

@chunhtai Here it is

@@ -17,6 +17,7 @@ dependencies:
go_router:
path: ..
logging: ^1.0.0
package_info_plus_web: ^2.0.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be removed?

@@ -3,6 +3,10 @@
- Updates compileSdkVersion to 33.
- Updates example app to iOS 11.

## 6.3.0

- Support for returning values on pop.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Support for returning values on pop.
- Supports for returning values on pop.

Copy link
Contributor

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

```dart
onTap: () {
final bool? result = await context.push<bool>('/page2');
WidgetsBinding.instance.addPostFrameCallback((_) {
Copy link
Contributor

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?

Copy link
Contributor Author

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);
Copy link
Contributor

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,
Copy link
Contributor

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,
Copy link
Contributor

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,
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@chunhtai
Copy link
Contributor

chunhtai commented Mar 3, 2023

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

@NazarenoCavazzon
Copy link
Contributor Author

let me know if there's another change to make

## 6.3.0

- Supports for returning values on pop.

## NEXT
Copy link
Contributor

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

Copy link
Contributor

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##NEXTas well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AHHHHH, got it

Copy link
Contributor

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]) {
Copy link
Contributor

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

Copy link
Contributor

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

Copy link
Contributor Author

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].
Copy link
Contributor

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]) {}
Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor Author

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.
Copy link
Contributor

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]) {}
Copy link
Contributor

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be private

Copy link
Contributor Author

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.

Copy link
Contributor

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]) {}
Copy link
Contributor

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be Object? ?

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@chunhtai chunhtai left a 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;
Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The future of the [RouteMatch] completer. When the future completes, this
/// The future of the [RouteMatch] completer.
///
/// When the future completes, this

Copy link
Contributor Author

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!

## 6.3.0

- Supports for returning values on pop.

## NEXT
Copy link
Contributor

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?

@chunhtai
Copy link
Contributor

chunhtai commented Mar 3, 2023

and the analyzer is not happy

@chunhtai chunhtai requested a review from hannah-hyj March 3, 2023 23:16
@NazarenoCavazzon
Copy link
Contributor Author

@chunhtai fixed the change log, almost forgot.

@booooohdan
Copy link

Waiting for resolving this PR

Copy link
Member

@hannah-hyj hannah-hyj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chunhtai chunhtai added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 20, 2023
@chunhtai
Copy link
Contributor

It looks like there is some conflict, can you rebase off the latest main?

@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Mar 23, 2023
@auto-submit
Copy link
Contributor

auto-submit bot commented Mar 23, 2023

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.

@NazarenoCavazzon
Copy link
Contributor Author

It looks like there is some conflict, can you rebase off the latest main?

Done

@@ -1,5 +1,6 @@
## 6.3.0

- Supports returning values on pop.
Copy link
Contributor

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

Copy link
Contributor Author

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

Copy link
Contributor

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 :(

Copy link
Contributor Author

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

Copy link
Contributor Author

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 🙃

Copy link
Contributor Author

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

Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chunhtai chunhtai added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 23, 2023
@auto-submit auto-submit bot merged commit 1f67d0c into flutter:main Mar 23, 2023
@tomassasovsky
Copy link
Contributor

grande naza!

@NazarenoCavazzon
Copy link
Contributor Author

Niceeeeeeeeee

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App p: go_router
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[go_router] callback function for go_router. [go_router] Update previous page on pop [go_router] Support return data from a screen with pop()
6 participants