I am using the AutoRoute package for Flutter.
I have the following two screens generated using the auto route package,
HomeRoute()
ProductsRoute()
Then from HomeRouteI do the following,
context.router.push(const ProductsRoute());
Then inside the ProductRoute I call an API in the initState and if I an error occurs, I show a pop up that says Something went wrong!. Here,
I want to pop the alert, then pop the ProductsRoute() so that the user navigates back to the HomeRoute().
So using the AutoRoute I did the following,
context.router.popUntil((route) => route.settings.name == 'HomeRoute')
This did not work. It leads me to a white screen.
However it does work if I do context.route.pop() twice.
Can someone please tell me what I am doing wrong and how can I navigate back to the HomeRoute() using the Auto Route package?
Thanks.
context.router.popUntil((route) => route.name == 'HomeRoute')
or
context.router.popUntilRouteWithName('HomeRoute')
I found the problem,
With popUntil, if I want to go to the HomeRoute, I should not mention the HomeRoute. Instead I should mention the route on the stack that is after the HomeRoute. Then it started to work,
For example suppose I have the following stack,
ScreenA -> ScreenB -> ScreenC -> ScreenD
Now if I want the user to show screen A by popping all the screens from screen D,
I should do,
context.router.popUntilRouteWithName(ScreenBRoute.name); // <---- Should do
NOT
context.router.popUntilRouteWithName(ScreenARoute.name); // <---- Should not do
Related
let's say I navigate from page a with context.push() and pass extra to page b.
then if I navigate to page c and then press the browser back button to go back to page b now extra is null and page shows error.
any solutions?
I think we can use query parameters but it brings up security problems.
You can follow one of the two possible solution:
Dont let page to come back to B from C, You can use something like popUntil
When coming back to B from C override the naviagetion such that you send the extra object along with it. So that B has extra value
Edit:
Presently there is no way to achieve this using go_router. You can use go_router_flow which is exactly like go_router with this pop with value feature.
final bool? result = await context.push<bool>('/page2');
WidgetsBinding.instance.addPostFrameCallback((_) {
if(result){
print('Page returned $result');
}
});
Use the beamer package for routing.This problem occur in the go router.
beamer package link
I am going to build flutter app with Getx.
I followed nested navigator from
https://github.com/jonataslaw/getx/issues/799#issuecomment-730719165
at this example, only shows 1 step sub routes like "/browse".
I need to make another sub routes like "/browse/tabX" and "/browse/tabY"
when click browse button from BottomNavigationBar, It shows tabs (tabX and tabY) on the top. and tabX is default selected.
for the body, it shows automatically their pages.
Also using Get.Named('/browse/tabY') can access to open their page(select second tab and show their body).
Can you help me?
Oh Now I got the answer!
What I make a mistake is I did not use "sub-name".
for example, at initialRoute,
I used '/home/browser' but it should be '/browser' if it is sub-route.
Because the concept is route to subrouter's root and handle by subrouter.
so "initialRoute from root" route to /home first.
and "initialRoute from subroute" route to /browser again!
I use classed variable instead just string so I did not figure this difference out.
When you pop the navigator too many times in Flutter you are met with a black screen. To prevent that from ever happening to the user because of some unforeseen event on my part, I have created the following function:
static void safePop<T extends Object>(BuildContext context, [T? result]) {
if (Navigator.canPop(context)) {
Navigator.of(context).pop<T>(result);
}
}
That works great for simple pops, but I've recently migrated my app to using named routes and would like to use the Navigator.popUntil(context, ModalRoute.withName()) to more accurately pop widgets when I'm 4 or 5 pages into the app. I'm having trouble figuring out a way to implement something similar to above with popUntil.
Is there a way to prevent the Navigator from popping to a black screen in case of an incorrect/non-existent route being passed to the popUntil function?
Thanks
I have a typical CRUD operation task: (List Sites, Add Site, ...)
I created a SitesProvider. In the same provider, I added 2 methods for add and edit. I was thinking to use the same provider in the 2 screens (ListSites and AddEditSite)
In the ListSites screen, it works fine. Here is the problem:
I open the AddSite screen by clicking the AddButton in the ListSites screen
Hit submit (did not enter data, simulating error case)
The error gets displayed in the ListSites screen, not in the AddSite screen.
It makes sense. They both use the same provider, both screens are on the stack. It seems that the first one only consumes the state update and displays the error.
I use MultipleProviders approach that wraps the MaterialApp with all providers in the app.
Can we fix that without creating separate providers for each of the 2 screens?
EDIT:
I used provider.removeListener in the ListSites screen right before I open the AddEdit and it shows the error in the correct screen now. I still have to do some other tweaks to get it back to listen after I add. Not efficient I think but it is a step.
I ended up doing that:
Added Another Field in the provider (stateType: list/addedit)
Change the type per the screen I'm currently in
provider.stateType = UIStateType.add_edit;
await Navigator.push(context,
MaterialPageRoute(builder: (context) => AddEditSiteScreen()));
provider.stateType = UIStateType.list;
in build(), I check for the type
sitesProvider = Provider.of(context);
if (sitesProvider.stateType != UIStateType.add_edit) return Container();
In my flutter app I use this code to go to my dashboard page, but it fails to do so the first time and I get the debugLocked error.
The launch page in the app is a Router that checks for shared preferences "sessionid" which, if set, takes the user directly to the Dashboard, else takes them to the login.
Without the below code, I get to my Dashboard just fine, using Navigator.pushReplacement() but then, a back arrow appears on the appBar. This back button takes the app back to the Router.
I searched for answers on how to remove all screens from the navigator and the following was what I found.
Navigator.of(context).popUntil(ModalRoute.withName(Dashboard.id));
Using the above code gives me the debugLocked error. Is there a solution to mitigate this problem? Or is there any other efficient way for me to remove screens from the context? Does setting automaticallyImplyLeading to false help somehow? Because this error only occurs after someone has logged in or signed up.
to remove all the previous routes use Navigator.pushAndRemoveUntil()
This can be another alternative, if you for some reason face a setState error.
navigationService.popUntil((_) => true);
navigationService.navigateTo(
'authentication',
);
basically i wait until the navigation finish setting everything and then call the navigateTo.