Flutter: How to get data back after pushReplacement removed a route? - flutter

So it goes like this. Let's say I want to get the data of the address, title, postal code and the coordinate pin point.
I want to make the user click on a button that brings them to the second page an asks for coordinate pinpoint first, then in the third page, I will ask for their title, address, and postalCode.
CreatePreloved -> PinPointPage -> AddressPage
However i want the user the user to not go back to PinPointPage after they have submitted their coordinate so I used pushReplacement.
CreatePreloved -> AddressPage
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => ShoppingCreatePrelovedAddressPage(
pickResult: result,
),
),
);
Then in the AddressPage the user can edit the pinpoint so I changed the function after the user choosed the pin in PinPointPage
CreatePreloved -> AddressPage -> PinPointPage
if (widget.initialPick != null) {
Navigator.pop(context, widget.initialPick);
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => ShoppingCreatePrelovedAddressPage(
pickResult: result,
),
),
);
}
The problem is I cannot pass the data back to the CreatePrelovedPage
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ShoppingCreatePrelovedPinPage(),
),
).then((value) {
log('value: $value');
if (value != null) { //value is null
setState(() {
_addressModel = value;
log('value: $value');
});
}
});
It says the value is null. How to pass back to data to the CreatePrelovedPage?

can you please try in following method
CreatePreloved -> AddressPage
Navigator.of(context).pushNamed(
ShoppingCreatePrelovedAddressPage,
arguments: result,
);
and here need to use arguments by calling following code CreatePreloved -> AddressPage -> PinPointPage
final result = ModalRoute.of(context).settings.arguments as String;
Navigator.of(context).pushNamed(
ShoppingCreatePrelovedAddressPage,
arguments: result,
);
again same logic applies below send arguments while navigating
note:use routes in main.dart to navigate
final result = ModalRoute.of(context).settings.arguments as String;
Navigator.of(context).pushNamed(
ShoppingCreatePrelovedPinPage,
arguments: result,
);

Related

Flutter: show dialogue with generate route

I have a page in my app where I give a file as a parameter but if the file is too large then I would like to stay at the same screen and with a warning message displayed using showDialogue. Since there are many entry points to this screen I am using generatedRoutes to check if the file will be rejected.
This check (the if statement) works at the moment , however, I have no idea how to stay on the screen and show the error. This is what I have so far:
Route<dynamic>? generateRoute(RouteSettings settings, BuildContext context) {
switch (settings.name) {
case homePage:
return MaterialPageRoute(builder: (context) => const HomePage());
case previewFilePage:
var file = settings.arguments as FileModel;
if (file.size > kMaxFileBytes) {
// What I want to do but doesnt work
showDialog(
context: context,
builder: (context) {
return PopUpDialogue(
message: Text("File is too large"),
);
}
);
break;
} else {
return MaterialPageRoute(
builder: (context) => PreviewFilePage(
file: file,
),
);
}
default:
return MaterialPageRoute(builder: (context) => const HomePage());
}
return null;
}
Is there a way to do this or will I have to add these error messages manually on each entry page? Also I know I could create an error page and direct to it if the check fails but I would much better prefer to have a dialogue show up instead.
Thanks!

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.
}

how to change webview payment to open in browser in flutter

I want the payment process to be done in the phone browser.
But now this operation is done according to the following code in webview.
Please help to replace the current mode.
this code:
/// Navigate to Webview payment
String? orderNum;
await FluxNavigate.push(
MaterialPageRoute(
builder: (context) => PaymentWebview(
url: url,
onFinish: (number) async {
orderNum = number;
},
)),
forceRootNavigator: true,
);
if (orderNum != null) {
cartModel.clearCart();
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WebviewCheckoutSuccessScreen(
order: Order(number: orderNum),
)),
);
}
return;
}
/// return success to navigate to Native payment
success!();
}

refresh previous page on Navigator.pop function

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);