refresh previous page on Navigator.pop function - flutter

Is there any way to refresh the previous page/ stack when Navigator.pop(context) is called? I need to do the API calling of the previous page to refresh the state of the page. The navigator.pop will sometimes be an alert dialog or maybe a back button. Is there a way to do the API calling? ThankYou.

use the then function after you push another route.
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => MyHomePage(),
),
).then(
(value) {
if (value) {
//refresh here
}
},
);
and when you return to previous screen, provide the pop function a value that determines whether to perform some action.
Navigator.of(context).pop(true);

Previous page
void goToNextPage()async {
var refresh = await Navigator.push(_context, new MaterialPageRoute(
builder: (BuildContext context) => new nextPage(context))
);
if(refresh ) setState((){});
}
NextPage
Navigator.pop(context, true);

Related

Flutter how to open page from push notification, context issue

void selectNotification(String? payload) async {
print('Selected notification');
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SearchScreen(),
),
);
}
I am using this method to open a screen when the notification is tapped, I get the print message fine but then the Navigator message shows:
The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
Im just trying to have it so if the notificaiton is tapped from foreground, background where ever the app then just pops open that screen but I cant get it to work
void selectNotification(String? payload, BuildContext context) async {
print('Selected notification');
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SearchScreen(),
),
);
}
Use getX package and use navigation routing:
something like this:
Get.put(()=> **your page**
getX package

Snackbar won't show when included in .then

So I have reusable snackbar on my code and I wanted to show my snackbar when user already pop from certain page. I tried to put my snackbar inside .then but It wont show anything. Any idea how to fix this ?
Here's my code:
void openChangeClientPage(BuildContext context, user){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddClientPage(
clientId: user!.uid,
clientNickname: Provider.of<UserDataProvider>(context, listen: false).userNickname,
clientProfileLink: Provider.of<UserDataProvider>(context, listen: false).userProfilePicture ?? '',
ticketData: ticketData,
ticketId: ticketId,
source: 'ticketDetail',
),
),
).then((value) {
if (value) {
ReusableSnackBar.buildSnackBar(context, 'New Client has been assigned');
Navigator.pop(context);
} else {
changeInvolvedState(true);
}
});
}
I think you can wrap the ReusableSnackBar into the Build method because snackbar tries to find the BuildContext closet but it is now in the Then method. You can read more in this
I think the code will be this:
void openChangeClientPage(BuildContext context, user){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddClientPage(
clientId: user!.uid,
clientNickname: Provider.of<UserDataProvider>(context, listen: false).userNickname,
clientProfileLink: Provider.of<UserDataProvider>(context, listen: false).userProfilePicture ?? '',
ticketData: ticketData,
ticketId: ticketId,
source: 'ticketDetail',
),
),
).then((value) {
if (value) {
Builder(builder: (context)=>ReusableSnackBar.buildSnackBar(context, 'New Client has been assigned'));
Navigator.pop(context);
} else {
changeInvolvedState(true);
}
});}
The issue is that you are calling Navigator.pop immediately after calling ReusableSnackBar. This will cause the SnackBar to pop too because you can assume the snackbar is like a pop-up/dialog and is immediately dismissed.
You can call Navigator.pop before displaying the snackbar.
You can also check out this answer if you want to show snackbar without context.
Firstly, make sure condition ("value" variable) is true.
Remove this line in your code:
Navigator.pop(context);
This code will close current screen, not dismiss snack bar.
If you want to dismiss snack bar, use:
ScaffoldMessenger.of(context).hideCurrentSnackBar();

Call a method on page pop

I'm pushing a new route like so in my app
Navigator.of(context)
.push<void>(
FilterTypesPage.routeFullScreen(context),
).then(
(value) {
log('PAGGGE POPPED');
},
),
static Route routeFullScreen(BuildContext context) {
return MaterialPageRoute<void>(
settings: const RouteSettings(name: routeName),
builder: (_) => BlocProvider.value(
value: BlocProvider.of<FeatureBloc>(context),
child: const FilterTypesPage(),
),
fullscreenDialog: true);
}
for some reason log('PAGGGE POPPED'); doesn't get called on page close
I'd like to trigger a bloc event or a function when I close this page
You should just call
Navigator.pop(context, someData);
from your RouteSettings where someData is the data you want to pass from the RouteSettings to the former page.
Then from your former page, you can perform your event handling inside the then block. The value inside the then block is the data that was passed from the RouteSettings page.
Alternatively, you can also use async-await instead of then in your former page.
onPressed: () async {
final someData = await Navigator.of(cotext).push(.....);
// Now perform your event handling which will be invoked after you pop `RouteSettings` page.
}

element data not refreshing

//calling a different class for dialog on submit click it's not updating list data
It's refreshing data but not going to the last opened tab on the second tab I perform this action but on tap, it's going on the first tab.
onTap: () {
setState(() {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) =>
EmployeePersonalDetailsUpdateActivity(_token),));
widget.listener.onEmployeeFamilyClick(_day, _month, _year,
_working);
});
Navigator.pop(context,true);
}
Your are calling your widget.listener after you navigate, call it before you navigate the route & if you want to pass the api response to the EmployeePersonalDetailsUpdateActivity widget, you must handle it, and it's your choice when you want to refresh your screen.
setState(() {
widget.listener.onEmployeeFamilyClick(_day,_month,_year,_working);
Navigator.pushReplacement(context, MaterialPageRoute(builder:
(context) => EmployeePersonalDetailsUpdateActivity(_token),));
});
There's another way:
widget.listener.onEmployeeFamilyClick(_day,_month,_year,_working).then((value) {
Navigator.pushReplacement(context, MaterialPageRoute(builder:
(context) => EmployeePersonalDetailsUpdateActivity(_token), value));
});
you can navigate your widget and pass the value of the response and show the updated value on the widget.

flutter call a function after moving back to screen from another screen

How to call a function in flutter ,after moving back to a screen from another screen?
For Example:
Screen 1
function1(){
}
Screen2
function2(){
//Go back to screen 1 and then call function1()
}
It's simple.
Navigator.push(context, MaterialPageRoute(builder: (context)=> SecondScreen())).then((_){
// This method gets callback after your SecondScreen is popped from the stack or finished.
function1();
});
You should also refer the Flutter Navigation & Routing.
Here is the solution!
Second Screen
Navigator.pop(context, [1]);
or, if you don't want to send back any data, you can only call
Navigator.pop(context);
First Screen
Navigator.push( context, MaterialPageRoute( builder: (context) => SecondScreen(), ), ).then((value) { //do something after resuming screen
});
Imho the solutions provided here aren't valid solutions.
If you use a routes Future it may be called multiple times and will even be called in case of a forward navigation.
Instead use a NavigatorObserver:
class AppNavigationObserver extends NavigatorObserver {
#override
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
print("AppNavigationObserver: ${route.settings.name}");
print("AppNavigationObserver: ${previousRoute?.settings.name}");
}
}
You can then use it for example like this:
MaterialApp(
navigatorObservers: [
AppNavigationObserver()
],
onGenerateRoute: (RouteSettings settings) {
return PageRouteBuilder(
maintainState: true,
settings: settings,
transitionDuration: const Duration(milliseconds: 300),
pageBuilder: (context, animation, secondaryAnimation) {
// Your route builder according to settings
},
);
},
)
The important part is passing onGenerateRoute's settings paramter to the PageRouteBuilder settings. Otherwise settings.arguments and settings.name will be null in the didPop handler.