I have to render screens condition wise. but conditions are not getting fulfilled.
My function is always returns the false boolean value even if it doesn't have to.
Here is my code
class _HomePageState extends State<HomePage> {
Future<bool> checkIsLoggedIn() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var data = await prefs.getString('isAuthenticated');
// the value of data is true here
print(data);
if (data == "true") {
return true;
} else {
return false;
}
}
@override
void initState() {
super.initState();
checkIsLoggedIn();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: checkIsLoggedIn() == true ? Profile() : LoginScreen());
//error : checkIsLoggedin () function returns false in my case.
}
}
CodePudding user response:
Use then()
to wait for the Future
. Then, assign the result with setState()
.
class _HomePageState extends State<HomePage> {
Future<bool> checkIsLoggedIn() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var data = await prefs.getString('isAuthenticated');
// the value of data is true here
print(data);
if (data == "true") {
return true;
} else {
return false;
}
}
var isLoggedIn = false; // HERE
@override
void initState() {
super.initState();
checkIsLoggedIn().then((result) { // HERE
setState(() {
isLoggedIn = result;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoggedIn == true // HERE
? Profile()
: LoginScreen());
}
}
CodePudding user response:
When getting into problems, I do recommend you are first looking into the warnings you are getting around the problematic area. If you are using a default Flutter project, you should have the lint unrelated_type_equality_checks
activated since it is part of the Core set of Dart Lints:
DON'T Compare references of unrelated types for equality.
Comparing references of a type where neither is a subtype of the other most likely will return false and might not reflect programmer's intent.
The problem is that your checkIsLoggedIn()
method have the following signature which means it returns an object of the type Future<bool>
:
Future<bool> checkIsLoggedIn() async {
And you are then comparing this against true
which are of the type bool
. If you are doing an equality check against these two different types, it will ALWAYS end up returning false
, which is also what you are observing.
A Future
also means that you are handling a value that are potentially still not created. So when you are running your checkIsLoggedIn() == true
it does not even know yet if the bool
inside your Future<bool>
are true
or false
.
The solution are to either make it so checkIsLoggedIn()
returns bool
, which cannot be done in this case since the method are handling asynchronously logic.
Another solution would then be to await
the returned Future
from checkIsLoggedIn()
. But we cannot use await
unless we mark the method, we are inside, as async
. But for Flutter, we are not allowed to have build()
marked as async
.
So a solution would instead be to handle the asynchronously nature of checkIsLoggedIn()
by using FutureBuilder
:
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
Which are a Widget
made for handling the building of the GUI when we don't know the value of the Future
, but then triggers an automatic rebuild when the value of the Future
are received.
CodePudding user response:
You can use .getbool instead .getString
To wait for checkIsLoggedIn result you can use a FutureBuilder.
Here an example :D
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
Future<bool> checkIsLoggedIn() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final isAuthenticated = await prefs.getBool('isAuthenticated');
return isAuthenticated;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<bool>(
future: checkIsLoggedIn(),
builder: (context, snapshot) {
// SHOW LOADING WHILE PREFS IS GETTING DATA
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
// SHOW SCREEN ACCORDING DATA
return snapshot.data! //
? const Profile()
: const LoginScreen();
},
),
);
}
}