9

I was trying to implement a simple login/logout functionality. My scenario is this:

I have 2 pages ( login page and home page), In the main.dart, I am using SharedPreferences to check if a user has already logged in or not if the user is logged in, I set a boolean value as true on click of a button.

The issue I am having is, I have a routeLogin function that I created to choose between Homepage and Landingpage. And I get this error:

I/flutter ( 9026): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 9026): The following assertion was thrown building MyApp(dirty):
I/flutter ( 9026): type 'Future<dynamic>' is not a subtype of type 'bool'
I/flutter ( 9026):
I/flutter ( 9026): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter ( 9026): more information in this error message to help you determine and fix the underlying cause.
I/flutter ( 9026): In either case, please report this assertion by filing a bug on GitHub:
I/flutter ( 9026):   https://github.com/flutter/flutter/issues/new?template=BUG.md

This is my code :

import 'package:credit/src/pages/landing.dart';
import 'package:flutter/material.dart';
import 'package:credit/src/pages/credit/home.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

 bool checkValue;
 checkLoginValue () async{
   SharedPreferences loginCheck = await SharedPreferences.getInstance();
   checkValue = loginCheck.getBool("login");
   }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Test App',
       debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: routeLogin());
      //home: LandingPage());      
  }

  routeLogin()
  {
    print("Check value");
    if (checkValue == null){
      return LandingPage();
    }
    else{
      return HomePage();
    }
    
  }
}

Please let me know where did I went wrong, I am new to Flutter.

Arun-
  • 846
  • 3
  • 22
  • 41
  • it doesn't make much sense to me that checkvalue might be equal to null in the route login function. why not make getbool function to return true if the shared preference contains value and false otherwise ? – Salma Jul 27 '19 at 13:45

3 Answers3

15

you can use future builder to obtain this behavior easily.

Future<bool> checkLoginValue() async {
  SharedPreferences loginCheck = await SharedPreferences.getInstance();
  return loginCheck.getBool("login");
}

@override
Widget build(BuildContext context) {
  return MaterialApp(
    title: 'Test App',
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: FutureBuilder<bool>(
      future: checkLoginValue,
      builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
        if (snapshot.data == false) {
          return LandingPage();
        } else {
          return HomePage();
        }
      },
    ),
  );
}
Sneha Singh
  • 143
  • 1
  • 14
Salma
  • 1,211
  • 2
  • 16
  • 33
  • This did help me, however I am a little confused, when I do print(checkLoginValue ()) it gives me an Instance of 'Future' I was expecting some value like nulll. Any idea how can get the value ? – Arun- Jul 27 '19 at 14:38
  • your method returns a future so you have to await the value. – Salma Jul 27 '19 at 14:39
  • thank you for that, if you can help understand where in the code do I need to put in await, that will help me understand a little better. – Arun- Jul 27 '19 at 14:42
  • i guess in checkLoginValue() before the return print(loginCheck.getBool("login")) – Salma Jul 27 '19 at 14:44
  • 1
    There is a type: inside FutureBuilder should it be "future: checkLoginValue()"; u missed the parenthesis. – Yogesh Apr 10 '21 at 15:46
7

Assuming that your getBool function from loginCheck returns Future,

You are trying to put a Future into a bool.

Change that line to:

checkValue = await loginCheck.getBool("login");
Pionix
  • 413
  • 2
  • 8
0

checkValue has a value of Future not a bool.

Future checkValue;

So you could check whether it has returned a value or an error.

routeLogin() {
  print("Check value");
  checkValue.then((res) {
    return LandingPage();
  }).catchError(
    (e) {
      return HomePage();
    },
  );
}
Sneha Singh
  • 143
  • 1
  • 14
10101010
  • 1,781
  • 1
  • 19
  • 25