GetxController onClose not called - flutter

I have a getx controllers A which has a property of another controller B. But when I delete the controller A, the onClose() of A is called while the onClose of B isn't.
// Controller A
#override
void onClose() {
print('close A');
B.dispose();
super.onClose();
}
//Controller B
#override
void onClose() {
print('close B');
animationController.dispose();
super.onClose();
}
until i add this line
#override
void onClose() {
B.onClose();
B.dispose();
super.onClose();
}
I'm newly interested in Getx, thanks for viewing this question:)

Is your controller B is being used by any other page/controller? If so, it's the expected behavior.
Also, you shouldn't call lifecycle methods (onInit, onClose) manually.

Related

Keep scroll controller open with Get.offNamed

i'm using Getx as state management
class ProductsController extends GetxController with StateMixin<Posts> {
ScrollController scrollController = ScrollController();
#override
void onInit() {
_getData();
scrollController = ScrollController()..addListener(_loadMore);
super.onInit();
}
_getData() async {}
_loadMore() async {}
#override
void onClose() {
scrollController.removeListener(_loadMore);
super.onClose();
}
}
and everything works perfectly, but for some reasons i need to navigate to same page as replacement by
Get.offNamed(Routes.products, prevent Duplicates: false);
but i note that this void
#override
void onClose() {
scrollController.removeListener(_loadMore);
super.onClose();
}
called and i lost the scroll in the bage ...
so how to keep scrollController open or how to initialize it again when navigate to the same page as replacement
or am i need to use another method to navigate to same page as replacement to it ??
thanks

Call api after bage build in getx

Im using getx and i want to call api after bage build, because this api its not necessary part of the page build.. What i know is this way
#override
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
});
}
But what about getx best way ?
the Getx package offers lifecycle methods that are very convenient in you're cases, what you need here is to use the onReady(), which is called one frame after the onInit() is executed, you can say that its equivalent to the:
#override
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
// Here is the code which will be executed exactly after initState using StatefulWidget
});
}
you can use onReady() like this:
class TextController extends GetxController {
#override
void onInit() {
/*...*/
}
void onReady() {
// Here is the code which will be executed exactly after onInit using Getx
}
}

Reinitialize Getx scrollController when navigate to same page

I use Get.offNamed to navigate to same page _ but this method called
#override
void onClose() {
scrollController.removeListener(_loadData);
super.onClose();
}
As a result I lose page scrolling How do I reset the scrollController
the Controller :
class PostsController extends GetxController with StateMixin<Posts> {
ScrollController scrollController = ScrollController();
#override
void onInit() {
_getData();
scrollController = ScrollController()..addListener(_loadMore);
super.onInit();
}
_getData() async {}
_loadMore() async {}
#override
void onClose() {
scrollController.removeListener(_loadMore);
super.onClose();
}
}
---I noticed Get.offNamed at first it reads the Controller of new page (in my case it's the same page)
[GETX] Instance "PostsController" has been created
[GETX] Instance "PostsController" has been initialized
Then deletes the controller of old page (in my case it's the same page)
[GETX] "PostsController" onDelete() called
[GETX] "PostsController" deleted from memory
Because of working in this order, the scrollController is lost. If it works the other way around the scrollController will be reinitialized.
I don't know how to go to the same page after deleting the controller (Firstly) and reinitializing it (secondly), or not calling onClose() when going to the same page as replacment
You can try initializing your scroll controller in the initstate like this:
class PostsController extends GetxController with StateMixin<Posts> {
late final ScrollController scrollController;
#override
void onInit() {
_getData();
scrollController = ScrollController()..addListener(_loadMore);
super.onInit();
}
_getData() async {}
_loadMore() async {}
#override
void onClose() {
scrollController.removeListener(_loadMore);
super.onClose();
}
}

Flutter GetX call fetch data only once in the build methode

I have a method called getData() which used to load data from API,
and i am displaying data in a separate screen, I have one issue which whenever I navigate to this page it rebuild the whole screen and call the API again and again.
PS: I'm using getX Obx to control the UI
Question: how to call the function only when new data has added
class CategoryPageBinding extends Bindings {
#override
void dependencies() {
Get.put(CategoryPageController(), permanent: true);
}
}
class CategoryPageController extends GetxController {
#override
void onInit() {
super.onInit();
getAllCategories();
}
}
You can call the method in Controller using getX.
#override
void onInit() {
super.onInit();
getData();
}

I need removelistener before ChangeNotifier disposed?

For example, i am call the controller.dispose() when page dispose, i also have to call the controller.removeListener?
TextEditingController _controller = TextEditingController();
#override
void initState() {
super.initState();
_controller.addListener(_listener);
}
void _listener() {
print(_controller.text);
}
#override
void dispose() {
// _controller.removeListener(_listener); //It is a must?
_controller.dispose();
super.dispose();
}
I see ChangeNotify source code about dispose
#mustCallSuper
void dispose() {
assert(_debugAssertNotDisposed());
_listeners = null;
}
I think is cleared listener, i am not need to call the removeListener method. But somebody tell me i need call the reamoveListener method before dispose method. I feel confused and want someone to tell me i am right or wrong. Thanks in advance!
Just called
_controller.dispose();
you don't need to call _controller.removeListener(_listener);