i have a little problem that make me crazy. I created a First Time Open section in my Flutter App that controlled by a flag in my SharedPreferences like this:
Future<void> main() async{
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences preferences = await SharedPreferences.getInstance();
initScreen = preferences.getInt('initScreen');
if (initScreen == 0 || initScreen == null) {
await preferences.setInt('initScreen', 1);
await preferences.setString('email', "");
await preferences.setString('firstName', "");
await preferences.setString('lastName', "");
await preferences.setString('phoneNumber', "");
await preferences.setString('address', "");
}
runApp(MyApp());
}
/*
void main() {
runApp(MyApp());
}
*/
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'My Title',
theme: theme(),
//initialRoute: SplashScreen.routeName,
initialRoute: initScreen == 0 || initScreen == null ? '/splash' : '/dashboard',
routes: routes,
);
}
}
In the First Time Section that i want to show there is the Login/Register form. So when the users insert their istances i want to save that in my SharedPreference:
class _SignFormState extends State<SignForm> {
...
String email;
SharedPreferences preferences;
Future<void> initSharedPreferences() async{
preferences = await SharedPreferences.getInstance();
}
Future<void> setEmail(String value) async{
preferences.setString('email', value);
}
Future<void> setInitScreenState(int value) async{
preferences.setInt('initScreen', value);
}
...
DefaultButton(
text: "Continue",
press: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
// If all are valid then go to success screen
setEmail(email);
setInitScreenState(1);
Navigator.pushNamed(context, LoginSuccessScreen.routeName);
}
},
),
Then in the dashboard i want to display for example the email that was insert in the preview route, or when the user re-open my app after he left and close it.
class Body extends StatefulWidget {
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
int initScreen;
String email;
SharedPreferences preferences;
Future<void> initSharedPreferences() async{
preferences = await SharedPreferences.getInstance();
}
Future<void> getSharedPreferences() async{
initScreen = await preferences.getInt('initScreen') ?? 0;
email = await preferences.getString('email') ?? 'Email not found';
}
@override
void initState() {
initSharedPreferences();
super.initState();
}
@override
Widget build(BuildContext context) {
getSharedPreferences();
return SingleChildScrollView(
child: Center(
child: Padding(
padding: EdgeInsets.all(kDefaultPadding),
child: Column(
children: [
Text("Dashboard temp.\n"),
Text("$initScreen"),
Text("$email"),
SizedBox(height: kDefaultPadding,),
MaterialButton(
child: Text("Logout", style: TextStyle(color: kWhiteColor, fontSize: 18),),
onPressed: () {},
height: kDefaultPadding,
color: kPrimaryColor,
padding: EdgeInsets.symmetric(horizontal: kDefaultPadding, vertical: 10.0),
),
],
),
),
),
);
}
}
But it doesn't work. And the function "preferences.getInt('initScreen') ?? 0;" or "preferences.getString('email') ?? 'Email not found';" always get my Null Error.
[VERBOSE-2:ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The method 'getInt' was called on null.
Receiver: null
Tried calling: getInt()
Thank you so much to read this question and if you leave a comment. Have a nice day
This is because your function initSharedPreferences() is a future and when getSharedPreferences() is called it has not resolved yet. Try getting your instance of sharedPreferences in getSharedPreferences() and also use setState() to update the value of email