I need to get the text wrote inside a ".txt" file, save it in a variable and give it to a Text, inside a TextField. 
The idea is to write the user input in a ".txt" file so he can read what he wrote when needed on the TextField.
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.
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.
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 ...');
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With