Home > Net >  In Dart/Flutter , how to wait until this callback async completes?
In Dart/Flutter , how to wait until this callback async completes?

Time:01-06

In flutter, I am using xml library to build xml

final builder = XmlBuilder();

builder.processing('xml', 'version="1.0"');


  builder.element("resources",
      namespaces: {"http://schemas.example.com/settings": "settings"},
      nest: await  () async  { // wait until this completes 
        await Future.forEach<String?>(keys, (element) async {
          final transString = await sheet.values.rowByKey(element!);
         
          builder.element("product", attributes: {"name": element},
              nest: () {
            builder.text(transString![allCols.indexOf("tay")]);
          });

        });

      });

  print(builder.buildDocument().toXmlString()); // this reaches before nest: function completes 

Now my problem is , in the builder.element(...) function call , there is a callback nest which builds inner nodes of XML

Inside nest I am using Google Sheets library to read data from a Google Sheet and append it to XML

Since sheet.values.rowByKey(..) is a Future function , I need to await to get the value and build the inner nodes

My problem is ,

after the line builder.processing('xml', 'version="1.0"'); , the execution directly comes to print(builder.buildDocument().toXmlString()) before the nest's callback got executed

That is , the builder.element (..) executed with it's first 2 params , but it skips to next line (print(..)) before the nest callback executed which is async

After this print , the block inside nest is executed !!!

So the print statements only print the XML with "< resources...>" tag , but not the inner tags

I tried putting await builder.element , but it's shows error since builder.element not return Future only void

So , how to make the builder.element to wait until it's nest block finishes execution and then proceeds to print

CodePudding user response:

There is a lot of method for await the data. I show you two method which i use mostly.

  1. FutureBuilder:

         FutureBuilder(
            future:yourMethod(),
            builder:(context,snapshot){
             if(snapshot.hasData){
               //Code Here
               return Container();
             }
             return CircularProgressIndicator();
         })
    

2.Using Method:

    Future<String> yourMethod() async{
    String data=await getDataFromApi();
    // Now you can use data variable inside code. its wait until data is assign
    return data;
    }

CodePudding user response:

Try waiting for your function to complete by putting await like this :

await builder.element("resources",
      namespaces: {"http://schemas.example.com/settings": "settings"},
      nest: await  () async  { // wait until this completes 
        await Future.forEach<String?>(keys, (element) async {
          final transString = await sheet.values.rowByKey(element!);
         
          builder.element("product", attributes: {"name": element},
              nest: () {
            builder.text(transString![allCols.indexOf("tay")]);
          });

        });

      });
  •  Tags:  
  • Related