Search code examples
flutterflutter-getx

How to make Flutter with GetX wait until data is loaded


I'm looking for a best-practice way to implement waiting for my app to initialize data before displaying the first page.

The app has a main controller as well as a controller per page. The main controller initially loads data from a server, and until that's done I'd like to display a splash page (or at least wait before opening the actual app-page)

An simple solution would be, that a page waits for the main controller to be initialized

class MainController extends GetxController {
  final isInitialized = false.obs;

  @override
  void onInit() async {
    Future f1 = server.get('service1').then(....)
    Future f2 = server.get('service1').then(....)
    Future f3 = server.get('service1').then(....)
    await Future.wait([f1, f2, f3]);
    isInitialized.value = true;
  }
}

And a page component could:

class HandleTaskPage extends GetView<HandleTaskPageController> {

  @override
  Widget build(BuildContext context) {
    MainController mainController = Get.find();

    return Obx(() {
        if (mainController.isInitialized().value) {
            return TaskPanelWidget();
        } else {
            return WaitingPage();
        }
    })
  }
}

But my app allows the user to start at any given page using a direct url (web-app) e.g. http://app.com/showtask/123 Which means that I must put the wait for global controller on every page.

Is there some way I could simply make Get wait (and possibly display a Welcome page) until GlobalController is ready before moving on to the page described in the route?

I've tried to add a WelcomePage to GetMaterialApp, to stop the app from going directly to the requested url. The WelcomeController should then await MainController before redirecting. But even though welcome-page does get rendered, the app still automatically continues to the page requested in the url.

void main() {
  runApp(GetMaterialApp(
    home: WelcomePage(),
    ...
    ...
    ...

Solution

  • You can implement mixin with name StateMixin.

    Example (Controller):

    class UserController extends GetxController with StateMixin {
        getData() {
            // make status to loading
            change(null, status: RxStatus.loading());
            
            // Code to get data
            await service.getData()
    
           // if done, change status to success
           change(null, status: RxStatus.success());
        }
    }
    

    Example (UI):

    class HomePage extends GetView<UserController> {
    
      @override
      Widget build(BuildContext context) {
    
        // controller from GetView
        return controller.obx((state) {
            return OtherWidget()
        },
        onLoading: CircularProgressIndicator(),
       )
      }
    }