3

I currently have many problems in my app with the get package for Flutter (https://pub.dev/packages/get) and the following state scenario:

For example I have a GetxController UserController. I need this controller in different Widgets, so I initialize it with Get.put() in the first widget and for the other child widgets I'll call it with Get.find(). That works.

But: I have some widgets that sometimes load before the controller got initialized and sometimes after. So I get many "UsersController" not found errors. Maybe there exists some workaround for this problem?

Vueer
  • 1,432
  • 3
  • 21
  • 57

5 Answers5

6

You could initialize your UsersController class using a Bindings class, prior to the start of your app.

Example

class UsersController extends GetxController {
  static UsersController get i => Get.find();
  int userId = 5;
}

class UsersBinding extends Bindings {
  @override
  void dependencies() {
    Get.put<UsersController>(UsersController());
  }
}

void main() async {
  UsersBinding().dependencies();
  runApp(MyApp());
}

Done this way your UsersController is guaranteed to be available everywhere in your app, prior to any Widgets loading.

class MyHomePage extends StatelessWidget {
  final UsersController uc = Get.find();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('GetX Bindings'),
      ),
      body: Center(
        child: Obx(() => Text('userId: ${uc.userId}')),
      ),
    );
  }
}
Baker
  • 24,730
  • 11
  • 100
  • 106
  • Is there any difference between what you've shown here and just putting `Get.put(UsersController());` right before `runApp(MyApp());`? Is the `Bindings` extension necessary? – Clifton Labrum Aug 27 '22 at 18:53
  • 1
    @CliftonLabrum This is the only thing I could find from the creator of the GetX project on why we'd use Bindings: https://github.com/jonataslaw/getx/issues/945#issuecomment-751182606 i.e. It's not necessary, but just organizes your Controller dependencies into a single spot that's (potentially) easier to switch between mocks / production code & naming is perhaps more intuitive ("Bindings"/"dependencies" is easier to guess its impact than "Get.put", which is more abstract) for collaborators who are unfamiliar with GetX. – Baker Aug 28 '22 at 21:04
  • I applied what I learned from your answer, as well as the use of getters, to make controller references really convenient: https://stackoverflow.com/a/73515232/1142348 – Clifton Labrum Aug 29 '22 at 14:53
  • @CliftonLabrum Thanks for note & link to your question. I added an answer to your question there, to address the other responses, which I believe are incorrect about placement of `Get.put` statements. It *should* be done within `build()` unless we're looking for persistence. – Baker Aug 29 '22 at 19:00
4

try to add

GetMaterialApp(
  smartManagement: SmartManagement.keepFactory,
)

so that it can store factory of those instanse

or make sure add permanent

Get.put<Repo>(Repo(), permanent: true);

so that it never get deleted from memory

GJJ2019
  • 4,624
  • 3
  • 12
  • 22
  • 1
    This will not work, because I have some widgets which are running before the controller itself was loaded. But for some situations I need this widget after the controller was loaded. In fact I need something like a condition: `Get.isInit(UsersController()) ? Get.find() : Get.put(UsersController)` .... – Vueer Nov 14 '20 at 06:58
1

if u need to check class is initialized, u most keep the class in memory with permanent:trueand set tag:'anything you want for check this object' property in Get.put function, and now u can check

bool Get.isRegistered<className>(tag: 'TagInPut')

Mohsen Haydari
  • 550
  • 5
  • 20
0

If there's no specific reason, you can just call Get.put(UserController()) at main function and wrap material app with GetMaterialApp.

hyobbb
  • 332
  • 1
  • 9
-1

if you are using get to provide an instance of something across your app meaby https://pub.dev/packages/get_it could help you more. just be sure that you use allowReassignment==true so you can update your instance if you want save a full new controller, but if you want to use the same always get_it is perfect for you