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!();
}
Related
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!
I am using Firebase authentication method to get detail info of the signed in user (i.e. displayname and photourl).
My code is as follow:
final user = FirebaseAuth.instance.currentUser!;
After succesfully signed in, I signed out to return to the login screen. However, when I tried to sign in again, I got an error referring to the code above:
"Null operator used on null value."
Any sugestion on the problem?
You have to listen to the auth state changes. Add this method to your Authentication class.
Future<void> initializeUser(BuildContext context) async {
FirebaseAuth.instance.authStateChanges().listen(
(User? user) async {
if (user == null) {
print('user is signed out');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoginScreen(),
),
);
} else {
await fetchUserData(); // handle fetching user data
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MyHomePage(),
),
);
print('user has signed in');
}
},
);
}
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();
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,
);
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);