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

[go_router] Come up with a better way to get the current location without context #129833

Open
2 tasks done
ghaith-abtah-5 opened this issue Jun 30, 2023 · 19 comments · May be fixed by flutter/packages#7651
Open
2 tasks done
Assignees
Labels
c: proposal A detailed proposal for a change to Flutter d: api docs Issues with https://api.flutter.dev/ p: go_router The go_router package P2 Important issues not at the top of the work list 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

@ghaith-abtah-5
Copy link

Is there an existing issue for this?

Use case

After the last update go_router 9.0.0, you have removed the location parameter from GoRouter and cannot be accessed any more without a context.

final GoRouter router = GoRouter(
     routes: [
          GoRoute(
                path: Routes.splashRoute,
                builder: (BuildContext context, GoRouterState state) {
                initSplashModule();
                return const SplashScreen();
                 },
               routes: [...],
               ],
            ),
           // other routes
        ],
     );

I cannot anymore use router.location to determine where am I in the application and there are certain scenarios where I cannot provide a context to GoRouterState.of(context).location, deep link or firebase messages that will pop or push some other routes from or to the navigation stack depending on the current location and state.
It was the easiest way to get the location and I can implement a way to do this on my own but it will take so much time and effort to get to the go_router package level.

Proposal

What was the reason to remove the location parameter and is there any chance that it will be back without a context in future versions?

@huycozy huycozy added the in triage Presently being triaged by the triage team label Jul 3, 2023
@huycozy
Copy link
Member

huycozy commented Jul 3, 2023

Hi @ghaith-abtah-5
As mentioned in Migration guide, you can work around this by following code (it is not guaranteed to work in later versions, though)

GoRouter _router;
final String location = _router.routerDelegate.currentConfiguration.uri.toString();
final bool canPop = _router.routerDelegate.canPop;

Please let us know your opinion if it applies to your case or not.

@huycozy huycozy added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jul 3, 2023
@ghaith-abtah-5
Copy link
Author

Thanks for reply.
I cannot relay on this method because of "it is not guaranteed to work in later versions", and there was no warning or deprecation annotation that you are going to remove the location property.
As I said, I can try to save the current route and implement this on my own but it will take time and effort.
What is the reason that it was removed without any warning?

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jul 9, 2023
@huycozy
Copy link
Member

huycozy commented Jul 10, 2023

Hi @ghaith-abtah-5,
The Migration guide has been updated after 9.0.2, you can try below sample migration code:

final RouteMatch lastMatch = _router.routerDelegate.currentConfiguration.last;
final RouteMatchList matchList = lastMatch is ImperativeRouteMatch ? lastMatch.matches : _router.routerDelegate.currentConfiguration;
final String location = matchList.uri.toString();

there was no warning or deprecation annotation that you are going to remove the location property.

Even though this is announced in the Changelog (this is a breaking change since 9.0.0), it should be warned in the API documentation. Thanks!

@huycozy huycozy added d: api docs Issues with https://api.flutter.dev/ package flutter/packages repository. See also p: labels. c: proposal A detailed proposal for a change to Flutter p: go_router The go_router package and removed in triage Presently being triaged by the triage team labels Jul 10, 2023
@ghaith-abtah-5
Copy link
Author

Thanks @huycozy for the clarification.
I still didn't get the reason why you have made this change where a lot of developers use the location propriety the old way but maybe they didn't notice the change yet and now we can get it in three lines of code instead of one simple line.

@danagbemava-nc danagbemava-nc added the team-go_router Owned by Go Router team label Jul 12, 2023
@chunhtai
Copy link
Contributor

The reason we remove the location is to avoid people looking up GoRouter.of(context).location since it will not rebuild the widget if it changes.

but i agree the current workaround is ugly

@chunhtai chunhtai changed the title [go_router] Getting the current location without context [go_router] Come up with a better way to get the current location without context Jul 13, 2023
@chunhtai chunhtai added P2 Important issues not at the top of the work list triaged-go_router Triaged by Go Router team labels Jul 13, 2023
@chrisdlangham
Copy link
Contributor

Here is a crazy idea. How about we have a method named 'location' that implements this workaround, then we don't have any breaking changes. Once we have a proper alternative solution then remove this location method.

@NullByte08
Copy link

Inspired by @chrisdlangham 's idea I have created this:

extension GoRouterExtension on GoRouter {
  String location() {
    final RouteMatch lastMatch = routerDelegate.currentConfiguration.last;
    final RouteMatchList matchList = lastMatch is ImperativeRouteMatch ? lastMatch.matches : routerDelegate.currentConfiguration;
    final String location = matchList.uri.toString();
    return location;
  }
}

for anyone else to use it. Just simply use it like this:

GoRouter.of(context).location()

@billy1380
Copy link

billy1380 commented Oct 17, 2023

Inspired by @chrisdlangham 's idea I have created this:

extension GoRouterExtension on GoRouter {
  String location() {
    final RouteMatch lastMatch = routerDelegate.currentConfiguration.last;
    final RouteMatchList matchList = lastMatch is ImperativeRouteMatch ? lastMatch.matches : routerDelegate.currentConfiguration;
    final String location = matchList.uri.toString();
    return location;
  }
}

for anyone else to use it. Just simply use it like this:

GoRouter.of(context).location()

make it a property and you are golden:

extension GoRouterLocation on GoRouter {
  String get location {
    final RouteMatch lastMatch = routerDelegate.currentConfiguration.last;
    final RouteMatchList matchList = lastMatch is ImperativeRouteMatch
        ? lastMatch.matches
        : routerDelegate.currentConfiguration;
    return matchList.uri.toString();
  }
}

@draskosaric
Copy link

Can I somehow get the access to parameters sent to current route?

@chunhtai chunhtai self-assigned this Nov 3, 2023
@chunhtai
Copy link
Contributor

chunhtai commented Nov 3, 2023

alright I will just add a getter to get routeMatchList in GoRouter. Though this is not critical as there is work around, but it is getting quite annoying when developing an app

@Vedsaga
Copy link

Vedsaga commented Nov 17, 2023

Inspired by @chrisdlangham 's idea I have created this:

extension GoRouterExtension on GoRouter {
  String location() {
    final RouteMatch lastMatch = routerDelegate.currentConfiguration.last;
    final RouteMatchList matchList = lastMatch is ImperativeRouteMatch ? lastMatch.matches : routerDelegate.currentConfiguration;
    final String location = matchList.uri.toString();
    return location;
  }
}

for anyone else to use it. Just simply use it like this:

GoRouter.of(context).location()

make it a property and you are golden:

extension GoRouterLocation on GoRouter {
  String get location {
    final RouteMatch lastMatch = routerDelegate.currentConfiguration.last;
    final RouteMatchList matchList = lastMatch is ImperativeRouteMatch
        ? lastMatch.matches
        : routerDelegate.currentConfiguration;
    return matchList.uri.toString();
  }
}

there is problem with the above approach as it seems the getter,

  /// The last matching route.
  RouteMatch get last => matches.last;

getter last tries to get the last element which likely be empty Array and so would return the error

image

Also, this issue very likely seems to cause the issue, #116855

will shared my code, which actually preventing that from happening issue...

@shibien
Copy link

shibien commented Jan 4, 2024

is it me or when I use this new way to get current location, it shows instead the previous location and not the current one ?... Is anyone having the same issue ?

@Vedsaga
Copy link

Vedsaga commented Jan 4, 2024

is it me or when I use this new way to get current location, it shows instead the previous location and not the current one ?... Is anyone having the same issue ?

Nope nope, actually it does current location.

@chris-wickens
Copy link

is it me or when I use this new way to get current location, it shows instead the previous location and not the current one ?... Is anyone having the same issue ?

Yes, if I use context.push instead of context.go the _router.routerDelegate.currentConfiguration.uri shows the previous location. I've switched to using context.go and it works now. If you previously awaited the push method's completion to do further work consider using GoRoute's onExit callback instead.

Possibly related: #132930

@flutter-triage-bot flutter-triage-bot bot added the Bot is counting down the days until it unassigns the issue label Mar 9, 2024
@flutter-triage-bot
Copy link

This issue is assigned to @chunhtai but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!

@flutter-triage-bot
Copy link

This issue was assigned to @chunhtai but has had no status updates in a long time. To remove any ambiguity about whether the issue is being worked on, the assignee was removed.

@flutter-triage-bot flutter-triage-bot bot removed the Bot is counting down the days until it unassigns the issue label May 25, 2024
@Tanmay-R-Choudhary
Copy link

Tanmay-R-Choudhary commented Jul 11, 2024

is it me or when I use this new way to get current location, it shows instead the previous location and not the current one ?... Is anyone having the same issue ?

For me, it is rebuilding all the routes that were previously injected in the stack (im using context.push to navigate). This might just be me though, as all the pages in my project have the same path: /:param1/:param2

I fetch additional data, via api call, based on the params and show content according to the response on the page. If I use context.go, everything works fine.

The reason I need to use context.push is to support back button presses on mobile. I found a related issue, that was seemingly, resolved in previous versions. I dont know if its the same bug. I solved the issue by adding the following code (which I found in a comment on the previous issue I mentioned):

Minimum code:

extension GoRouterLocation on GoRouter {
  String get location {
    final RouteMatch lastMatch = routerDelegate.currentConfiguration.last;
    final RouteMatchList matchList = lastMatch is ImperativeRouteMatch
        ? lastMatch.matches
        : routerDelegate.currentConfiguration;
    return matchList.uri.toString();
  }
}

// in the route list ->
GoRoute(
      path: '/:num',
      builder: (context, state) {
        if (state.matchedLocation != GoRouter.of(context).location) {
          return const SizedBox.shrink();
        }

        context.read<AppBloc>().add(Reload(url: state.pathParameters['num']!)); // api call

        return const Renderer();
      },
    )

Here is the link to the comment: #123570 (comment)

@chunhtai chunhtai self-assigned this Aug 1, 2024
@chunhtai chunhtai added the triaged-go_router Triaged by Go Router team label Aug 1, 2024
@kevlar700
Copy link

I was happy with Vrouter but it's dependencies not being updated in two years just broke my app.

Vrouters ability to get the current url was nicer tbh

selected: (context.vRouter.url == "my_url"),

@iapicca
Copy link
Contributor

iapicca commented Sep 13, 2024

I was happy with Vrouter but it's dependencies not being updated in two years just broke my app.

Vrouters ability to get the current url was nicer tbh

selected: (context.vRouter.url == "my_url"),

I thought the point was NOT to use context

@cedvdb cedvdb linked a pull request Sep 15, 2024 that will close this issue
11 tasks
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 d: api docs Issues with https://api.flutter.dev/ p: go_router The go_router package P2 Important issues not at the top of the work list 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
None yet
Development

Successfully merging a pull request may close this issue.