How to fix error: type 'Null' is not a subtype of type '() => void'

612
onPressed: _adminIDController.text.isNotEmpty && _passwordController.text.isNotEmpty
  ? logInAdmin()
  : () => showDialog(

above, what you are saying is if a condition is true (in this case the condition is both _adminIDController and _passwordController to not be empty) then it should run logInAdmin and wait for it to finish and then run whatever logInAdmin returned.

Dart thinks logInAdmin will return a function and it should run that function. This is not the case, you want the button to directly run logInAdmin.

To fix this, remove the parenthesis:

onPressed: _adminIDController.text.isNotEmpty && _passwordController.text.isNotEmpty
  ? logInAdmin
  : () => showDialog(

This way, you are not assigning the result of the function, you are assigning the function itself.

Also as a general recommendation, you should always declare a return type on your functions so dart can tell you whenever this happens

void logInAdmin() {
  ...
Share:
612
Carleton Y
Author by

Carleton Y

Entrepreneur learning Dart and Flutter to build a social app for my large number of social media followers. I started learning how to code with Dart and Flutter for the first time in my life in August 2021.

Updated on January 02, 2023

Comments

  • Carleton Y
    Carleton Y over 1 year

    I have an admin sign in page where admins can add an id and password to gain access to the Admin area. There is an admin collection in the Firebase Database that stores the id and password. The admin collection is separate from the user sign in page and separate from the user collection which uses Firebase Authentication before allowing access. The user access continues to work correctly. When I fill in the two input boxes on the admin sign in screen and click the button to gain access my error dialog message appears indicating that there isn't any data in the two input fields even though there is data. If I do nothing to the code and then hot reload and click the button again I am able to access the admin but I get the following error message in the console.

    The following _TypeError was thrown building ShoppingAdminSignInPage(dirty, dependencies: [_LocalizationsScope-[GlobalKey#2c797]], state: _ShoppingAdminSignInPageState#e3b3d): type 'Null' is not a subtype of type '() => void'

    I have obviously written something or several things incorrectly in my code. It appears the error is in the ShoppingAdminSignInButton. Thank you in advance for any help.

    class ShoppingAdminSignInPage extends StatefulWidget {
      const ShoppingAdminSignInPage({Key? key}) : super(key: key);
    
      @override
      State<ShoppingAdminSignInPage> createState() =>
          _ShoppingAdminSignInPageState();
    }
    
    class _ShoppingAdminSignInPageState extends State<ShoppingAdminSignInPage> {
      final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
      final TextEditingController _adminIDController = TextEditingController();
      final TextEditingController _passwordController = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return AdaptiveLayoutScaffold(
          appBar: const ShoppingAdminSignInPageAppBar(),
          landscapeBodyWidget: Container(),
          portraitBodyWidget: SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              child: Column(
                mainAxisSize: MainAxisSize.max,
                children: [
                  const ShoppingAdminSignInHeader(),
                  Form(
                    key: _formKey,
                    child: Column(
                      children: [
                        const SizedBox(
                          height: 50.0,
                        ),
                        AdminSignInTextField(
                          controller: _adminIDController,
                          labelText: TextFieldLabel.adminID,
                          prefixIcon: Icons.person,
                          textInputAction: TextInputAction.next,
                        ),
                        AdminSignInTextField(
                          controller: _passwordController,
                          labelText: TextFieldLabel.password,
                          prefixIcon: Icons.password,
                          textInputAction: TextInputAction.done,
                        ),
                        ShoppingAdminSignInButton(
                          onPressed: _adminIDController.text.isNotEmpty &&
                                  _passwordController.text.isNotEmpty
                              ? logInAdmin()
                              : () => showDialog(
                                  context: context,
                                  builder: (ctx) {
                                    return const ErrorAlertDialog(
                                      message: DialogString.addAdminIDAndPassword,
                                    );
                                  }),
                        ),
                        const NotAnAdminButton(),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
      logInAdmin() {
        FirebaseFirestore.instance.collection('admins').get().then((snapshot) {
          snapshot.docs.forEach((result) {
            if (result.data()['id'] != _adminIDController.text.trim()) {
              SnackBarUtil.showSnackBar(
                context,
                SnackBarString.idNotCorrect,
              );
            } else if (result.data()['password'] !=
                _passwordController.text.trim()) {
              SnackBarUtil.showSnackBar(
                context,
                SnackBarString.passwordNotCorrect,
              );
            } else {
              SnackBarUtil.showSnackBar(
                context,
                'Welcome ${result.data()['name']}',
              );
              setState(() {
                _adminIDController.text = '';
                _passwordController.text = '';
              });
              Navigator.pushReplacement(
                context,
                MaterialPageRoute(
                  builder: (context) => const UploadItemsPage(),
                ),
              );
            }
          });
        });
      }
    }
    
  • Carleton Y
    Carleton Y over 2 years
    thank you for your quick response. Your answer makes sense although I wouldn't have figured it out on my own. I updated my code to remove the parentheses and to add void in front of the LogInAdmin method. There must be some other issue with my code too because even after the change it only works after I hit hot restart. It's very strange. But at least now there aren't any error messages in the console. @h8moss
  • h8moss
    h8moss over 2 years
    @CarletonY Sorry, could you be more specific? What only works after you hit hot-restart? Is it the ternary? if it is, would you mind adding a setState(() {}); on the onChanged method of your text fields and seeing if that it the issue?
  • Carleton Y
    Carleton Y over 2 years
    no need to be sorry @h8moss. I used your very detailed answer to rethink things, fix the error and then I rewrote the code in a way where everything is working perfectly. There are no issues with hot restart, the ternary or anything else. Thanks again for your tremendous help.
  • h8moss
    h8moss over 2 years
    @CarletonY I see, I am happy to have helped you!