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.
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")]);
});
});
});
