qlevar_router
qlevar_router copied to clipboard
Navigation issue with QRoute.withChild while using replaceLastName or replaceAllWithName
Hi @SchabanBo, there is an issue with the replaceLastName or replaceAllWithName while using with QRoute.withChild.
Let suppose say we have some onBoardingPages & some dashboardPages. Now as user has signed in or signed-up we will take the user to dashboard page & as user don't want to come back to onBoardingPages once signed up or sign-in, So I am using replaceLastName/replaceAllWithName to replace the onBoardingPagesCompletely with DashboardPages. Now in dashboardPages there is an logout option so clicking on it we will use replaceAllWithName(to delete complete stack no matter how may pages) & send the user to onBoardingPages. Now at this point after logout if user navigates between the pages of sign-up/sign-in/forgot-password pages then the below errors will pop up
Errors:-
- Take user to dashboard page by clicking on login option & clicks on logout option. Now you will be in sign-in page, now click on sign-up button to navigate to sign-up page then error come as "Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: -1". But the correct way is user should navigate between sign-in/sign-up pages smoothly without any errors.
- Take user to dashboard page by clicking on login option & clicks on logout option. Now you will be in sign-in page, now click on forgot-password button. You will be navigated to forgot password back & at this point click on back button then error comes as "Unhandled Exception: Bad state: No element". But the correct way is user should go back to sign-in page.
Below is the reproducible code
import 'package:flutter/material.dart';
import 'package:qlevar_router/qlevar_router.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final routes = [
QRoute(
name: 'sign-in',
path: '/sign-in',
builder: () => const SignInPage(),
),
QRoute(
name: 'sign-up',
path: '/sign-up',
builder: () => const SignUpPage(),
),
QRoute(
name: 'sign-up',
path: '/sign-up',
builder: () => const SignUpPage(),
),
QRoute(
name: 'forgot-password',
path: '/forgot-password',
builder: () => const ForgotPassword(),
),
QRoute.withChild(
name: 'dashboard',
path: '/dashboard',
initRoute: '/home',
children: [
QRoute(
name: 'home',
path: '/home',
builder: () => ElevatedButton(
onPressed: () => QR.navigator.replaceAllWithName('sign-in'),
child: const Text('Logout'),
),
)
],
builderChild: (router) => Dashboard(router: router),
),
];
MyApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp.router(
routeInformationParser: const QRouteInformationParser(),
routerDelegate: QRouterDelegate(routes, initPath: '/sign-in'),
theme: ThemeData.dark(),
);
}
class SignInPage extends StatelessWidget {
const SignInPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('Sign In'),
centerTitle: true,
),
body: Column(
children: [
TextField(),
ElevatedButton(
onPressed: () => QR.toName('forgot-password'),
child: const Text('Forgot-Password'),
),
ElevatedButton(
onPressed: () => QR.navigator.replaceLastName('sign-up'),
child: const Text('Sign-Up'),
),
ElevatedButton(
onPressed: () => QR.navigator.replaceLastName('dashboard'),
child: const Text('Login'),
),
],
),
);
}
class SignUpPage extends StatelessWidget {
const SignUpPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('Sign Up'),
centerTitle: true,
),
body: Column(
children: [
TextField(),
ElevatedButton(
onPressed: () => QR.navigator.replaceLastName('sign-in'),
child: const Text('Sign-In'),
),
ElevatedButton(
onPressed: () => QR.navigator.replaceLastName('dashboard'),
child: const Text('Login'),
),
],
),
);
}
class ForgotPassword extends StatelessWidget {
const ForgotPassword({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('Forgot password'),
centerTitle: true,
),
body: Column(
children: [
ElevatedButton(
onPressed: () => QR.back(),
child: const Text('Go back'),
),
],
),
);
}
class Dashboard extends StatelessWidget {
final QRouter router;
const Dashboard({Key? key, required this.router}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('Dashboard'),
centerTitle: true,
),
body: router,
);
}