'Flutter: fill a textfield with a string on shared preferences

I'm trying to fill a textfield with a string stored on shared preferences, but I don't understand how to do it.

The case is:

1 - I log in on the first screen.

2 - The username is saved on shared preferences.

3 - Then the second screen is called with some text fields.

4 - The username field should be filled with the user that was saved.

Here is how i store the username on the first screen:

 final prefs = await SharedPreferences.getInstance();
                      final key = 'user';
                      final value = loggedUser;
                      prefs.setString(key, value);
                      print('saved $value');

And here is the function that I use on the second screen to retrieve the username:

 static _read() async {
    final prefs = await SharedPreferences.getInstance();
    final key = 'user';
    final value = prefs.getString(key);
    print('saved $value');
    String usu = value;
  }

I can load the username on the second screen but I can't put it on a textfield, how can I do that?

I have tried a little modification on the function (below) and them passing the function on the text controller but doesn't worked, I guess its not the right way.

  static _read() async {
    final prefs = await SharedPreferences.getInstance();
    final key = 'usuario';
    final value = prefs.getString(key);
    print('saved $value');
    String usu = value;
    return usu; //the modification
  }

The controller:

final _pecasController = TextEditingController(text: _read());


Solution 1:[1]

I finally did it.

Thanks for the guys who commented here and helped me, it wasnt working so i made a search and finally managed to make it work.

Here's the codes

The function:

 static _read() async {
    final prefs = await SharedPreferences.getInstance();
    final key = 'usuario';
    final value = prefs.getString(key);
    print('saved tester $value');
    String usu = value;
    return usu;

  }

The initstate:

  @override
  void initState() {
    super.initState();
    _read();

    WidgetsBinding.instance.addPostFrameCallback((_) async {
      _usuarioController.text = await _read();
    });

I don't know if this is the best way to make it, but it worked and thats all i need for now.

Solution 2:[2]

As I was in the same boat, even though this answer is old, I felt like i wanted to give an answer. I would have posted this in the comments but am unable to do so atm.

@override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await _read();
    });
  }

The inital code can be smaller, there is no need to load the _read() before the WidgetsBinding. All it does is call it twice.. For readability I would also suggest making the _read() call shorter, and make it a normal Future so you will be sure the return type is String. Also privatised the values.

Future<void> _read() async {
    final _prefs = await SharedPreferences.getInstance();
    final _value = _prefs.getString('usuario');
    print('saved tester $_value');
    setState(() {
      _usuarioController.text = value;
    });
  
  }

I know the previous answer was correct and it worked, but this is better.

Solution 3:[3]

Does this work for you?

class TheState extends State<TheWidget> {

  TextEditingController _pecasController = TextEditingController();

  @override
  void initState() async {
    _pecasController.text = await _read();
  }

Solution 4:[4]

use setState() method and update the textController of textfield with updated string.

final TextEditingController _mobile = TextEditingController(text: '');

String mobileString = '1238892922';

setState((){
_mobile.text = mobileString;
}
)

And the textfield text will be this 1238892922

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 abrev
Solution 2
Solution 3 Falko
Solution 4 Nisha Jain