I'm working with ionic react and I want to use useIonViewDidEnter in the menu component but useIonViewDidEnter in the menu component doesn't work and nothing showing in the console, anyone can help, please?
const ManagerMenu: React.FC = () => {
useIonViewDidEnter(() => {
console.log('isAuthorizedToSeeContracts')
})
It only works in pages I believe.
I suggest you manage the authState either through a property, context, or something else.
Related
I expected this issue to have a simple solution but I didn't find yet any...
I have few tabs in my app, in one of them I open another screen using
Navigator.push(context, MaterialPageRoute(...
Once user clicks on a button in that screen I want to pop it and navigate to another tab.
I tried to pass TabController to the relevant tab and its child screen, but this doesn't seem like the simplest solution, and also not easy to accomplish since the controller is not yet defined:
tabController = DefaultTabController(
body: TabBarView(
children: [
FirstTab(
tabController: tabController // <- tabController is not defined yet at this point:(
Is there any "global" function to reset the app's "entire" route so it will both pop MaterialPageRoute and navigate to specific tab ?
You can use Navigator.of(context).pushReplacement
The solution I found is to call Navigator's push synchronously and check for its returned value. Then when I want to navigate to another tab I simply send true indication in Navigator's pop.
This is how my navigation method looks like, notice I had to add a short delay before navigating to another tab, not sure why, but it didn't work without it:
_navigateToDetailsScreen() async {
bool shouldNavigateToHomeTab = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailsScreen()),
));
if (shouldNavigateToHomeTab) {
Future.delayed(const Duration(milliseconds: 500), () {
DefaultTabController.of(context)!.animateTo(0);
});
}
}
And this is how I call pop:
Navigator.of(context).pop(true);
This looks like the simplest solution for me, and so far I didn't find any issues with it.
I am using getX. I just need once the application opened, the data from database shown. I created a future function inside the repository and need to auto-display it. if it call this function inside onInit inside the controller the lat variable will not be initialized yet. i need to call this function inside the binding but this error occurs.
HomeController" not found. You need to call "Get.put(HomeController())" or "Get.lazyPut(()=>HomeController())"
The Code Inside Binding Is:
Get.lazyPut<IHomeRepository>(
() => HomeRepoFirebaseImplimentation(),
);
// Get.lazyPut<HomeController>(
Get.putAsync(
() async=>await HomeController(homeRepository: Get.find()).fetchProductsFromDB(),
);
I was experiencing the same problem, and nothing worked.
But studying my structure further and in more detail, I had the following tree:
BasePage
| -> HomePage
| -> CartPage
| -> OrdersPage
And what happened was that I was trying to put the binding on my HomePage directly, but as my base that would do the navigation through the PageView, I needed to create a Binding in the Base that stores the Controllers of each view.
This made it work perfectly.
More practically, I did this:
class BaseBindings implements Bindings {
#override
void dependencies() {
Get.put(HomeController());
Get.put(CartController());
Get.put(OrdersController());
}
}
And in getPages I did the following:
GetPage(
name: '/base',
page: () => const BasePage(),
binding: BaseBindings(),
),
This made the application work normally and I had more peace of mind in the development; that's what worked.
The new Material UI DatePicker has a renderInput prop that gets a function that renders a text field. Works well enough, except that this function is rendered twice, and on first render it only receives some of the props it needs.
When rendered with React Testing Library, only the first render happens. Notably, the endAdornment is not present. So it's impossible to getByRole('button') and click the button to open the picker modal.
I've tried various permutations of waitFor() and rerender() but can't seem to get the button to show up.
Here's a code sandbox that shows the two versions of the renderInput params being logged out. (I've also got a test in there to look for the button, but unfortunately I'm also doing something wrong with the test and it's not running.)
Any suggestions?
It is because Mui’s DatePicker render mobile view by default.
Below would fix it:
beforeEach(() => {
// add window.matchMedia
// this is necessary for the date picker to be rendered in desktop mode.
// if this is not provided, the mobile mode is rendered, which might lead to unexpected behavior
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: (query: string): MediaQueryList => ({
media: query,
// this is the media query that #material-ui/pickers uses to determine if a device is a desktop device
matches: query === '(pointer: fine)',
onchange: () => {},
addEventListener: () => {},
removeEventListener: () => {},
addListener: () => {},
removeListener: () => {},
dispatchEvent: () => false,
}),
});
});
afterEach(() => {
delete window.matchMedia;
});
For more details: github issue
I it possible to see the navigator stack with GetX? I looked in the documentation but I could not find anything on this subject. I usually close for example dialogs like this
Get.until((route) => !Get.isDialogOpen);
But I was wondering if I could close routes if an instance of a specific page is in the routing history which would be something like this
Get.until((route) => !Get.routingHistory.contains('/someRoute'));
Note this isn't valid syntax.
You need to use:
Get.offUntil(page, (route) => false)
page means the new page to navigate.
(route) => false
Is the condition.
Get.until
Remove screens until satisfying the condition.
It’s the same with Navigation.popUntil().
You can use it like Get.until((route) => Get.currentRoute == '/home').
Get.offNamed
By the Named route, remove the current screen and add a new screen.
It’s the same with Navigation.pushReplacementNamed().
You can use it like Get.offNamed('/second').
Get.offAndToNamed
By the Named route, add a new screen and then, remove the previous screen.
It’s the same with Navigation.popAndPushNamed().
You can use it like Get.offAndToNamed('/second').
Get.offUntil
Remove screens until satisfying the condition, and then, add a new screen.
It’s the same with Navigation.pushAndRemoveUntil().
You can use it like Get.offUntil(page, (route) => (route as GetPageRoute).routeName == '/home').
Get.offNamedUntil
By the Named route, remove screens until satisfying the condition, and then, add a new screen.
It’s the same with Navigation.pushNamedAndRemoveUntil().
You can use it like Get.offNamedUntil(page, ModalRoute.withName('/home')).
Please use according to your usecase
GetX have another useful function:
int times = 2;
Get.close(times);
Close as many routes as defined by [times]
If you want to keep closing routes until you reach a page route....
Navigator.of(context).popUntil(ModalRoute.withName('/route-name'));
It is possible. Navigator.popUntil pops pages until a passed predicate returns true. We can query the following route in the navigator stack and decide what decision to make.
The GetX method for doing the same is
`
Get.offUntil( MaterialPageRoute(builder: (context) => const NewPage()), (route) {
var currentRoute = route.settings.name;
debugPrint("Get.currentRoute --- $currentRoute");
if(currentRoute == "/Home") {
return true;
} else {
return false;
}
}
`
The code above pops until home. Also, we can add custom logic in the if-else block above.
Get.until((route) {
if (route.settings.name == Routes.TEST1) {
//Return to the specified page
return true;
} else {
return false;
}
});
Get.offAll(Home()); // remove all previous routes and redirect to home
of with namedRoutes:
Get.offAllNamed('/home');
I have a TextFormField. Usually you can use the selection toolbar to copy/paste/select all and so on using long tap/double tap.
I want to overwrite the Paste Event. It shouldn't simple insert the current clipboard data but open a popup with several options to insert.
Is it possible to catch and overwrite the Paste event in any way? I saw something like handlePaste() for SelectionControls, but I don't know how to add this to my TextFormField.
Thanks in advance!
AFAIK, you can't exactly 'intercept' the standard toolbar. However, what you can do is to prevent the standard toolbar and make your own.
You can use wrap the textfield/textformfield under IgnorePointer. It will hide any tap gestures on the text field. Below is the code snippet.
IgnorePointer(
child: TextField(
focusNode: _textfieldFocusNode,
controller: _controller,
),
)
Now,you can wrap this IgnorePointer under GestureDetector and show your own menu. Like this :
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
FocusScope.of(context).requestFocus(_textfieldFocusNode);
},
onLongPress: () {
showMenu(____
}
)
This produces the result below and the sample implementation code is here
Found a way to override paste event. I'm not sure, that it is a right way, but it works.
In every TextField you have selectionControls, that provides a way to show and handle toolbar controls.
So, to catch paste event first:
create your own version of selection controls, for example
class AppCupertinoTextSelectionControls extends CupertinoTextSelectionControls {
AppCupertinoTextSelectionControls({
required this.onPaste,
});
ValueChanged<TextSelectionDelegate> onPaste;
#override
Future<void> handlePaste(final TextSelectionDelegate delegate) {
onPaste(delegate);
return super.handlePaste(delegate);
}
}
class AppMaterialTextSelectionControls extends MaterialTextSelectionControls {
AppMaterialTextSelectionControls({
required this.onPaste,
});
ValueChanged<TextSelectionDelegate> onPaste;
#override
Future<void> handlePaste(final TextSelectionDelegate delegate) {
onPaste(delegate);
return super.handlePaste(delegate);
}
}
then, initialise it in your state (for example in StatefulWidget it can looks like that, see below). To study how it used in TextField please see source here
TextSelectionControls? _selectionControls;
#override
void initState() {
if (widget.onPaste != null) {
if (Platform.isIOS) {
_selectionControls = AppCupertinoTextSelectionControls(
onPaste: widget.onPaste!,
);
} else {
_selectionControls = AppMaterialTextSelectionControls(
onPaste: widget.onPaste!,
);
}
}
super.initState();
}
Use callback for onPaste with a type ValueChanged<TextSelectionDelegate> and you can use the same code the Flutter team used to get Clipboard data:
Future<void> onPastePhone(final TextSelectionDelegate? delegate) async {
final TextSelection selection = phoneController.selection;
if (!selection.isValid) {
return;
}
// Snapshot the input before using `await`.
// See https://github.com/flutter/flutter/issues/11427
final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
final text = data?.text ?? '';
if (text.isEmpty) {
return;
}
}
Then use selection controls in your TextField.
TextFormField(
selectionControls: _selectionControls,
)
Hope it helps.
I search for this problem. I think there is no proper way to solve this problem. I read about the Textfield class and found two solutions for it.
if you check TextField widget you can find that it will use EditableText to show its simple Text input. EditableText has a selectionControls property. this property is used to render the selection toolbar. also, I found that material and Cupertino have different implementation of it.
1st Solution: you can create your own custom TextField that will use EditableText and pass your custom selectionControl to your widget. I think this gonna be a very hard job to do. create your own implementation of the widget, handling animations, and...
2nd Solution: You can simply copy all related files of TextField in a new file and update it as you want. for this solution, I create a repo in GitHub. you can checkout source code to understand how you can show a dialog in the paste option. and this is how the code should work.
note: I just simply update paste function of the Material implementation of selectionControls. if you want you can also update the Cupertino selectionControls too.
note: also I added documents in everywhere I change the code.