Is there a way to load async data on InitState method?

前端 未结 9 1509
你的背包
你的背包 2020-12-05 16:39

I\'m a looking for a way to load async data on InitState method, I need some data before build method runs. I\'m using a GoogleAuth code, and I need to execute build method

相关标签:
9条回答
  • 2020-12-05 17:21
      @override
      void initState() {
        super.initState();
        asyncInitState(); // async is not allowed on initState() directly
      }
    
      void asyncInitState() async {
        await yourAsyncCalls();
      }
    
    0 讨论(0)
  • 2020-12-05 17:23

    Previous Answer!!

    You can set a Boolean value like loaded and set it to true in your listen function and make your build function return your data when loaded is set to true otherwise just throw a CircularProgressIndicator

    Edited -- I would not suggest calling setState in a method you call in initState. If the widget is not mounted while the setState is called (as the async operation completes) an error will be reported. I suggest you use a package after_layout

    Take a look at this answer for better understanding setState in initState : https://stackoverflow.com/a/53373017/9206337

    This post will give you an idea to know when the app finishes the build method. So that you can wait for your async method to setState after widget is mounted : https://stackoverflow.com/a/51273797/9206337

    0 讨论(0)
  • 2020-12-05 17:24

    You can create an async method and call it inside your initState

           @override
            void initState () {
              super.initState();
              WidgetsBinding.instance.addPostFrameCallback((_){
                _asyncMethod();
              });
    
            }
    
            _asyncMethod() async {
             _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount account)     {
                setState(() {
                  _currentUser = account;
                });
              });
              _googleSignIn.signInSilently();
            }
    
    0 讨论(0)
  • 2020-12-05 17:25

    Sweet and Short :

    (() async { await your_method(); setState(() {....anything here}); })();

    0 讨论(0)
  • 2020-12-05 17:30

    Sample code:

     @override
      void initState() {
        super.initState();
    
        asyncOperation().then((val) {
          setState(() {});
          print("success");
        }).catchError((error, stackTrace) {
          print("outer: $error");
        });
    
    //or
    
        asyncOperation().whenComplete(() {
          setState(() {});
          print("success");
        }).catchError((error, stackTrace) {
          print("outer: $error");
        });
      }
    
      Future<void> asyncOperation() async {
        await ... ;
      }
    
    0 讨论(0)
  • 2020-12-05 17:34

    I came here because I needed to fetch some files from FTP on program start. My project is a flutter desktop application. The main thread download the last file added to the FTP server, decrypts it and displays the encrypted content, this method is called from initState(). I wanted to have all the other files downloaded in background after the GUI shows up.

    None of the above mentioned methods worked. Constructing an Isolate is relatively complex.

    The easy way was to use the "compute" method:

    1. move the method downloading all files from the FTP out of the class.
    2. make it an int function with an int parameter (I do not use the int parameter or the result)
    3. call it from the initState() method

    In that way, the GUI shows and the program downloads the files in background.

      void initState() {
        super.initState();
        _retrieveFileList(); // this gets the first file and displays it
        compute(_backgroundDownloader, 0); // this gets all the other files so that they are available in the local directory
      }
    
    int _backgroundDownloader(int value) {
      var i = 0;
      new Directory('data').createSync();
      FTPClient ftpClient = FTPClient('www.guckguck.de',
          user: 'maxmusterman', pass: 'maxmusterpasswort');
      try {
        ftpClient.connect();
        var directoryContent = ftpClient.listDirectoryContent();
        // .. here, fileNames list is reconstructed from the directoryContent
    
        for (i = 0; i < fileNames.length; i++) {
          var dirName = "";
          if (Platform.isLinux)
            dirName = 'data/';
          else
            dirName = r'data\';
          var filePath = dirName + fileNames[i];
          var myDataFile = new File(filePath);
          if (!myDataFile.existsSync())
            ftpClient.downloadFile(fileNames[i], File(filePath));
        }
      } catch (err) {
        throw (err);
      } finally {
        ftpClient.disconnect();
      }
      return i;
    
    0 讨论(0)
提交回复
热议问题