TextFormField does not reflect initialValue from a ChangeNotifierProvider

111 Views Asked by At

I am trying to set the initialValue of my TextFormField from my provider. This works but not on inital load of my screen. For this to work, I need to go to previous screen, then come back. Here are the relevant source codes.

User class:

class User with ChangeNotifier {
  String name;
  String email;

  User() {
    _deserialiseUser();
  }
}

void _deserialiseUser() async {
  final prefs = await SharedPreferences.getInstance();
  final String jsonUser = prefs.getString('user');
  if (jsonUser != null) {
    var ju = jsonDecode(jsonUser);
    name = ju['name'];
    email = ju['email'];
    notifyListeners();
  }
}

Main class:

void main() => runApp(
  MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (context) => User()),
      ...
    ],
    child: MyApp(),
  ),
);

The affected screen:

class AccountScreen extends StatefulWidget {
  @override
  _AccountScreenState createState() => _AccountScreenState();
}

class _AccountScreenState extends State<AccountScreen> {
  User user;
  @override
  Widget build(BuildContext context) {
    user = context.watch<User>();
    return Scaffold(
      appBar: AppBar(
        title: Text('Account'),
      ),
      body: TextFormField(
        initialValue: user.name,
      ),
    );
  }
}

If I replace my TextFormField with Text, this works fine. What am I missing?

1

There are 1 best solutions below

0
On BEST ANSWER

EDIT: Although I already have the answer, I will still accept answers that can explain the root cause of the issue.

I solved the issue by not lazily loading my User provider like so:

void main() => runApp(
  MultiProvider(
    providers: [
      ChangeNotifierProvider(
        create: (context) => User(),
        lazy: false,
      ),
    ],
    child: MyApp(),
  ),
);