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] Query Parameters are not preserved on pop #116872

Open
sarbagyastha opened this issue Dec 12, 2022 · 14 comments
Open

[go_router] Query Parameters are not preserved on pop #116872

sarbagyastha opened this issue Dec 12, 2022 · 14 comments
Labels
found in release: 3.3 Found to occur in 3.3 found in release: 3.7 Found to occur in 3.7 has reproducible steps The issue has been confirmed reproducible and is ready to work on 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

@sarbagyastha
Copy link
Contributor

sarbagyastha commented Dec 12, 2022

Steps to Reproduce

Run the code snippet
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

final router = GoRouter(
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return Scaffold(
          body: child,
          bottomNavigationBar: Text(state.location),
        );
      },
      routes: [
        GoRoute(
          path: '/',
          builder: (context, state) {
            return Page(
              pageNo: 1,
              argument: 'default',
              onTap: () => router.go('/page2?a=apple'),
            );
          },
          routes: [
            GoRoute(
              path: 'page2',
              builder: (context, state) {
                return Page(
                  pageNo: 2,
                  argument: state.queryParams['a'].toString(),
                  onTap: () => router.go('/page2/page3?b=ball'),
                );
              },
              routes: [
                GoRoute(
                  path: 'page3',
                  builder: (context, state) {
                    return Page(
                      pageNo: 3,
                      argument: state.queryParams['b'].toString(),
                    );
                  },
                ),
              ],
            ),
          ],
        ),
      ],
    ),
  ],
);

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Go Router Query Demo',
      theme: ThemeData.from(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.red),
      ),
      routerConfig: router,
    );
  }
}

class Page extends StatelessWidget {
  const Page({
    super.key,
    required this.pageNo,
    required this.argument,
    this.onTap,
  });

  final int pageNo;
  final String argument;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    final nextPage = pageNo + 1;

    return Scaffold(
      appBar: AppBar(title: Text('Page $pageNo')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Argument: ${argument.toUpperCase()}'),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: onTap,
              child: Text('Go to Page $nextPage'),
            ),
            Padding(
              padding: const EdgeInsets.only(top: 16),
              child: ElevatedButton(
                onPressed: pageNo > 1 ? router.pop : null,
                child: const Text('Go back'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
  1. Go to Page 2 and then Page 3
  2. Tap on Go back once

Tested with: go_router: ^5.2.4

Expected results:

image

Actual results:

image

flutter doctor -v
[✓] Flutter (Channel stable, 3.3.9, on macOS 13.0.1 22A400 darwin-arm, locale
    en-NP)
    • Flutter version 3.3.9 on channel stable at
      /Users/sarbagya/Development/flutter
    • Upstream repository ssh://git@github.com/flutter/flutter.git
    • FLUTTER_GIT_URL = ssh://git@github.com/flutter/flutter.git
    • Framework revision b8f7f1f986 (3 weeks ago), 2022-11-23 06:43:51 +0900
    • Engine revision 8f2221fbef
    • Dart version 2.18.5
    • DevTools version 2.15.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/sarbagya/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • ANDROID_HOME = /Users/sarbagya/Library/Android/sdk
    • Java binary at: /Users/sarbagya/Library/Application
      Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335
      /Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14B47b
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • CHROME_EXECUTABLE = /Users/sarbagya/Development/chrome

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build
      11.0.13+0-b1751.21-8125866)

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/sarbagya/Library/Application
      Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9014738
      /Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build
      11.0.13+0-b1751.21-8125866)

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/sarbagya/Library/Application
      Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335
      /Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build
      11.0.13+0-b1751.21-8125866)

[✓] VS Code (version 1.73.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.42.0

[✓] Connected device (3 available)
    • iPhone 14 Pro Max (mobile) • A4987323-FA06-400E-99D9-4909D34428C8 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-16-1 (simulator)
    • macOS (desktop)            • macos                                •
      darwin-arm64   • macOS 13.0.1 22A400 darwin-arm
    • Chrome (web)               • chrome                               •
      web-javascript • unknown

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!
@exaby73 exaby73 added the in triage Presently being triaged by the triage team label Dec 12, 2022
@exaby73
Copy link
Member

exaby73 commented Dec 12, 2022

Triage report

I can reproduce this issue with go_router: 5.2.4 on all platforms. What I noticed is that the query params from the current route, in this case page 3, is still there and not replaced with the query params of the previous route, in this case page 2.

Here is how the URLs look on web:

  • First is /
  • Click on Page 2 to go to /page2?a=apple
  • Click on Page 3 to go to /page2/page3?b=ball
  • Click on Back

Expected URL should be /page2?a=apple
Actual URL is /page2/?b=ball

Code Sample
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

final GoRouter router = GoRouter(
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return Scaffold(
          body: child,
          bottomNavigationBar: Text(state.location),
        );
      },
      routes: [
        GoRoute(
          path: '/',
          builder: (context, state) {
            return Page(
              pageNo: 1,
              argument: 'default',
              onTap: () => router.go('/page2?a=apple'),
            );
          },
          routes: [
            GoRoute(
              path: 'page2',
              builder: (context, state) {
                return Page(
                  pageNo: 2,
                  argument: state.queryParams['a'].toString(),
                  onTap: () => router.go('/page2/page3?b=ball'),
                );
              },
              routes: [
                GoRoute(
                  path: 'page3',
                  builder: (context, state) {
                    return Page(
                      pageNo: 3,
                      argument: state.queryParams['b'].toString(),
                    );
                  },
                ),
              ],
            ),
          ],
        ),
      ],
    ),
  ],
);

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Go Router Query Demo',
      theme: ThemeData.from(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.red),
      ),
      routerConfig: router,
    );
  }
}

class Page extends StatelessWidget {
  const Page({
    super.key,
    required this.pageNo,
    required this.argument,
    this.onTap,
  });

  final int pageNo;
  final String argument;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    final nextPage = pageNo + 1;

    return Scaffold(
      appBar: AppBar(title: Text('Page $pageNo')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Argument: ${argument.toUpperCase()}'),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: onTap,
              child: Text('Go to Page $nextPage'),
            ),
            Padding(
              padding: const EdgeInsets.only(top: 16),
              child: ElevatedButton(
                onPressed: pageNo > 1 ? router.pop : null,
                child: const Text('Go back'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

@exaby73 exaby73 added package flutter/packages repository. See also p: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on p: go_router The go_router package found in release: 3.3 Found to occur in 3.3 found in release: 3.7 Found to occur in 3.7 p: first party and removed in triage Presently being triaged by the triage team labels Dec 12, 2022
@stuartmorgan stuartmorgan added the P2 Important issues not at the top of the work list label Dec 13, 2022
@johnpryan
Copy link
Contributor

Thanks for filing an issue, this is something we should fix.

@loshine
Copy link

loshine commented Apr 25, 2023

We are facing the same problem when developing our applcation.

So any progress on this problem? will it be fixed soon?


Now I am using extra to pass parameters to avoid this situation.

@flutter-triage-bot flutter-triage-bot bot added multiteam-retriage-candidate team-go_router Owned by Go Router team triaged-go_router Triaged by Go Router team labels Jul 8, 2023
@OpenSphereSoftware
Copy link

We cannot use this router if that does not work.

@michalss
Copy link

is it fixed ?? still happening...

@hagen00
Copy link

hagen00 commented Sep 14, 2023

Same problem here!

@gosoares
Copy link

gosoares commented Sep 17, 2023

I'm facing the same issue, it seems to be pretty old: csells/go_router#170.

It's a very strange behavior, this should have more priority.

@RenanDelfanti
Copy link

Any solution?

@dannndi
Copy link

dannndi commented Oct 29, 2023

it's not the perfect solution, but i found the workaround using this one
set GoRouter.optionURLReflectsImperativeAPIs = true;
and instead using context.go("/page2/page3?b=ball") use context.push("/page2/page3?b=ball") instead.
still don't know whats the cost/downside, but it work

@alexgiura
Copy link

Any change? I have same problem when I'm using " Navigator.pop(context)" querryParams are preserved.

@GZaccaroni
Copy link

GZaccaroni commented Dec 15, 2023

The issue persists on Go Router 12.1.3. I have updated the code sample of @exaby73 :

Code sample
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

final GoRouter router = GoRouter(
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return Scaffold(
          body: child,
          bottomNavigationBar: Text(GoRouterState.of(context).matchedLocation)
        );
      },
      routes: [
        GoRoute(
          path: '/',
          builder: (context, state) {
            return Page(
              pageNo: 1,
              argument: 'default',
              onTap: () => router.go('/page2?a=apple'),
            );
          },
          routes: [
            GoRoute(
              path: 'page2',
              builder: (context, state) {
                return Page(
                  pageNo: 2,
                  argument: GoRouterState.of(context).uri.queryParameters['a'].toString(),
                  onTap: () => router.go('/page2/page3?b=ball'),
                );
              },
              routes: [
                GoRoute(
                  path: 'page3',
                  builder: (context, state) {
                    return Page(
                      pageNo: 3,
                      argument: GoRouterState.of(context).uri.queryParameters['b'].toString(),
                    );
                  },
                ),
              ],
            ),
          ],
        ),
      ],
    ),
  ],
);

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Go Router Query Demo',
      theme: ThemeData.from(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.red),
      ),
      routerConfig: router,
    );
  }
}

class Page extends StatelessWidget {
  const Page({
    super.key,
    required this.pageNo,
    required this.argument,
    this.onTap,
  });

  final int pageNo;
  final String argument;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    final nextPage = pageNo + 1;

    return Scaffold(
      appBar: AppBar(title: Text('Page $pageNo')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Argument: ${argument.toUpperCase()}'),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: onTap,
              child: Text('Go to Page $nextPage'),
            ),
            Padding(
              padding: const EdgeInsets.only(top: 16),
              child: ElevatedButton(
                onPressed: pageNo > 1 ? router.pop : null,
                child: const Text('Go back'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
flutter doctor -v

[✓] Flutter (Channel stable, 3.13.9, on macOS 14.2 23C64 darwin-arm64, locale en-IT)
    • Flutter version 3.13.9 on channel stable at /Users/gzaccaroni/fvm/versions/stable
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision d211f42860 (7 weeks ago), 2023-10-25 13:42:25 -0700
    • Engine revision 0545f8705d
    • Dart version 3.1.5
    • DevTools version 2.25.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
    • Android SDK at /Users/gzaccaroni/Library/Android/sdk
    • Platform android-34, build-tools 33.0.1
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15C65
    • CocoaPods version 1.13.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.3.1)
    • IntelliJ at /Applications/IntelliJ IDEA.app
    • Flutter plugin version 77.0.1
    • Dart plugin version 233.11799.172

[✓] VS Code (version 1.85.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (3 available)
    • macOS (desktop) • macos                     • darwin-arm64   • macOS 14.2 23C64 darwin-arm64
    • Chrome (web)    • chrome                    • web-javascript • Google Chrome 120.0.6099.109

[✓] Network resources
    • All expected network resources are available.

• No issues found!

@fabioafreitas
Copy link

it's not the perfect solution, but i found the workaround using this one set GoRouter.optionURLReflectsImperativeAPIs = true; and instead using context.go("/page2/page3?b=ball") use context.push("/page2/page3?b=ball") instead. still don't know whats the cost/downside, but it work

This solved my issue

@esDotDev
Copy link

esDotDev commented Jan 16, 2024

Seems like there are two specific behaviors here. There's the concept of pop which is moving up a stack of pages, and back which is going back in history.

When we move back it's possible to restore the previous urlParams (via history). When we pop it may not be possible to restore the previous page params.

I think the behavior most expected by devs is an API like backOrPop()

  • If the router has history, a BackBtn will move back to the previous page url, restoring any previous params
  • If there is no history (a deeplink), then the function will try to pop up the stack

It would also be nice to augment this with a router.clearQueryParams().

@Fingertips18
Copy link

Any updates on this? The issue still exists to this date.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
found in release: 3.3 Found to occur in 3.3 found in release: 3.7 Found to occur in 3.7 has reproducible steps The issue has been confirmed reproducible and is ready to work on 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
No open projects
Status: Todo
Development

No branches or pull requests