I am creating an app that logs in users and saves the user's data locally. The problem is it displays null when I try to display it on a text field or something but when I print said variable inside the function, it displays the value. I'm not sure what the problem is here.
Here's the code.
String? email = '';
void getEmail() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SharedPreferences prefs = await _prefs;
setState(() {
email = prefs.getString('username');
});
}
So the 'email' variable is what keeps returning null, as you can see in the function, when the 'getEmail' is called, it should reassign the 'email' variable to the acquired value.
When I try to display it, it returns null or nothing at all, but when I call a print in the fuction, it returns the true value, what is the problem here?
Example
void getEmail() async{
...
email = prefs.getString('username');
print(email);
the result of this would be 'jafar'
but if I call it in a Text or whatnot in the build Method, For example
TextButton(onPressed: (){getEmail();
print(email);}, child: Text('click')),
Text('${email}')
everything returns null; what is the problem?
Complete Code
class Example extends StatefulWidget {
const Example({Key? key}) : super(key: key);
State createState() => _ExampleState();
}
class _ExampleState extends State {
@override
Widget build(BuildContext context) {
FirebaseAuth auth = FirebaseAuth.instance;
String? email = '';
void getEmail() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SharedPreferences prefs = await _prefs;
setState(() {
email = prefs.getString('username');
});
}
return Scaffold(
body: SafeArea(child: Column(children: [
TextButton(onPressed: (){getEmail();
print(email);}, child: Text('click')),
Text('${email}')
],),)
);
}
}
CodePudding user response:
Your getEmail
is Future, so you should await for it, so change:
void getEmail() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SharedPreferences prefs = await _prefs;
setState(() {
email = prefs.getString('username');
});
}
to
Future getEmail() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SharedPreferences prefs = await _prefs;
setState(() {
email = prefs.getString('username');
});
}
then In your onPress
:
onPressed: () {
await getEmail();
print(email);
},
But I recommended you use this approach:
first change your getEmail()
to this:
Future<String?> getEmail() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SharedPreferences prefs = await _prefs;
return prefs.getString('username');
}
then use it this way:
onPressed: () {
var _email = await getEmail();
if(_email!= null){
print(_email);
setState(() {
email = _email;
});
}
},
Full working example:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: EmailWidget(),
);
}
}
class EmailWidget extends StatefulWidget {
const EmailWidget({Key? key}) : super(key: key);
@override
State<EmailWidget> createState() => _EmailWidgetState();
}
class _EmailWidgetState extends State<EmailWidget> {
Future<String?> getEmail() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SharedPreferences prefs = await _prefs;
return prefs.getString('username');
}
Future setEmail() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SharedPreferences prefs = await _prefs;
return prefs.setString('username', 'amir');
}
String? email;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.purple[50],
appBar: AppBar(
title: Text('fist'),
),
body: Column(
children: [
TextButton(
onPressed: () async {
var result = await getEmail();
if (result != null) {
setState(() {
email = result;
});
print(result);
} else {
await setEmail();
}
},
child: Text('click'),
),
Text('${email}')
],
),
);
}
}
Result: