Call async functions in build method flutter
Solution 1
You are using an asynchronous value in a rendering process (the build function of a stateful/stateless widget) which is synchronous. You can't just put a Future
of String
into a place of a String
. It won't work. Why? Because it is of a different type, and you need special methods to convert a variable from one type to another.
In this case, you might want to transform this Future
into a String
asynchronously during the build process. You can use a FutureBuilder
for that.
return FutureBuilder<String>(
future: _myRead,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data);
} else {
return Text('awaiting the future');
}
},
);
If you don't transform this Future
into a String
to be rendered, it will just be an Instance of Future
.
Solution 2
you should use a FutureBuilder if you wanna render something that takes time (asynchronous)
FutureBuilder(
future:_myRead,
builder: (ctx,snapshot) {
if(snapshot.connectionState == connectionState.waiting) {
return // your waiting Widget Ex: CircularLoadingIndicator();
} else if (snapshot.hasData) {
return Text(snapshot.data.toString()); // toString() is just to be safe
} else { //probably an error occured
return Text('Something went wrong ...');
}
Micheal Ross
Updated on December 21, 2022Comments
-
Micheal Ross over 1 year
I need to get the text wrote inside a ".txt" file, save it in a variable and give it to a
Text
, inside aTextField
. The idea is to write the user input in a ".txt" file so he can read what he wrote when needed on theTextField
.All works, when I read the file it takes the right content but when I store it in a variable to use it
Text(var_name...)
well what I read on the screen is "Instance of 'Future'".I know this problem comes from a bad handling of async and future but I would like to really understand why this isn't working.
This is my code :
Future<String> get _localPath async { final directory = await getApplicationDocumentsDirectory(); return directory.path; } Future<File> get _localBio async { final path = await _localPath; print(path); return File('$path/bio.txt'); } Future<File> _write(String text, String filename) async { final file = await _localBio; // Write the file. return file.writeAsString(text); } Future<String> _read() async { try { final file = await _localBio; String body = await file.readAsString(); // Read the file. return body; } catch (e) { // If encountering an error, return 0. return "Can't read"; } } Future<String>_MyRead() async { String read_ = await _read(); print(read_); return read_; }
Please write a full answer, I tried a lots of video, forums...Don't just tell me to do
var str= _MyRead().then((value) => value);
Maybe it can be the answer but please write 2 more lines because I want to understand why this isn't working. I took the code from dev official documentation.-
Benedikt J Schlegel almost 4 yearsHave you confirmed it writes the string correctly? The issue is just in reading?
-
Micheal Ross almost 4 yearsCurrently I wrote the string in the file by my hand and the "write" doesn't work, I tested it now. I'm new in Flutter maybe I'm calling the functions in a bad way... In the variable, after reading, "null" is stored.
-
-
Micheal Ross almost 4 yearsOooooh ok now I understand. Thank you very clear. I will study this FutureBuilder. I thought that using a ".then" I could transform a "Future<String>" to String. The only way to do this transformation is with a "FutureBuilder"?