2

I am trying to navigate to a new screen by pressing the "Process Order" Button but I keep getting the error [VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: Null check operator used on a null value. I am not sure where exactly the error is happening.

I've been struggling with the for a while now. What could be the issue here?

class CartScreen extends StatefulWidget {
  const CartScreen({
    Key? key,
  }) : super(key: key);

  static const routeName = '/cart-screen';

  @override
  State<CartScreen> createState() => _CartScreenState();
}

class _CartScreenState extends State<CartScreen> {
  final user = FirebaseAuth.instance.currentUser;  

  final TextEditingController deliveryNoteController = TextEditingController();
  bool isLoading = false;

  @override
  Widget build(BuildContext context) {
    final cart = Provider.of<Cart>(context);
    return isLoading
        ? const LoadingSpinner()
        : Scaffold(
            appBar: AppBar(
              automaticallyImplyLeading: false,
              elevation: 0,
              iconTheme: IconThemeData(color: Colors.blueGrey[900]),
              title: const Text(
                'Order Summary',
                style: TextStyle(color: Colors.black),
              ),
            ),
            body: cart.totalAmount <= 0
                ? const EmptyCartScreen()
                : SingleChildScrollView(
                    child: Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 15.0),
                      child: Column(
                        children: <Widget>[
                          StreamBuilder<DocumentSnapshot>(
                              stream: FirebaseFirestore.instance
                                  .collection('users')
                                  .doc(user!.uid)
                                  .snapshots(),
                              builder: (context, snapshot) {
                                if (snapshot.hasError) {
                                  return const Text(
                                      'Oops, something went wrong.');
                                }
                                if (!snapshot.hasData) {
                                  return const LoadingSpinner();
                                }
                                DocumentSnapshot? doc = snapshot.data;
                                return Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    ListView.builder(
                                      physics:
                                          const NeverScrollableScrollPhysics(),
                                      shrinkWrap: true,
                                      scrollDirection: Axis.vertical,
                                      itemCount: cart.items.length,
                                      itemBuilder: (context, i) => CartItem(
                                        cart.items.values.toList()[i].id,
                                        cart.items.keys.toList()[i],
                                        cart.items.values.toList()[i].price,
                                        cart.items.values.toList()[i].quantity,
                                        cart.items.values
                                            .toList()[i]
                                            .title
                                            .toString(),
                                      ),
                                    ),
                                    Row(
                                      children: [
                                        const Text(
                                          'Delivery Address',
                                          style: TextStyle(
                                            fontWeight: FontWeight.w600,
                                            fontSize: 16.0,
                                          ),
                                        ),
                                        const Spacer(),
                                        TextButton(
                                          child: const Text('Edit'),
                                          onPressed: () {
                                            showModalBottomSheet(
                                              context: context,
                                              builder: (context) =>
                                                  const Padding(
                                                padding: EdgeInsets.symmetric(
                                                  horizontal: 20.0,
                                                  vertical: 30.0,
                                                ),
                                                child: EditDeliveryInfoForm(),
                                              ),
                                            );
                                          },
                                        ),
                                      ],
                                    ),
                                    Column(
                                      children: [
                                        ListTile(
                                          horizontalTitleGap: 0.0,
                                          visualDensity: const VisualDensity(
                                              horizontal: 0, vertical: -4),
                                          leading: const Icon(
                                              Ionicons.location_outline),
                                          title: Text(doc!['address']),
                                        ),
                                        ListTile(
                                          horizontalTitleGap: 0.0,
                                          visualDensity: const VisualDensity(
                                              horizontal: 0, vertical: -4),
                                          leading: const Icon(
                                              Ionicons.person_outline),
                                          title: Text(doc['name']),
                                        ),
                                        ListTile(
                                          horizontalTitleGap: 0.0,
                                          visualDensity: const VisualDensity(
                                              horizontal: 0, vertical: -4),
                                          leading:
                                              const Icon(Ionicons.call_outline),
                                          title: Text(doc['phoneNumber']),
                                        ),
                                        const SizedBox(
                                          height: 10.0,
                                        ),
                                        TextField(
                                          controller: deliveryNoteController,
                                          decoration: InputDecoration(
                                            hintText: 'Delivery note',
                                            enabledBorder: OutlineInputBorder(
                                              borderRadius:
                                                  BorderRadius.circular(8.0),
                                              borderSide: BorderSide(
                                                color: Colors.grey.shade400,
                                                width: 1.6,
                                              ),
                                            ),
                                            focusedBorder: OutlineInputBorder(
                                              borderRadius:
                                                  BorderRadius.circular(8.0),
                                              borderSide: BorderSide(
                                                color: Colors
                                                    .lightBlueAccent.shade700,
                                                width: 1.6,
                                              ),
                                            ),
                                          ),
                                        ),
                                        const SizedBox(
                                          height: 12.0,
                                        ),
                                      ],
                                    ),
                                    const Divider(
                                      thickness: 1.2,
                                    ),
                                    Padding(
                                      padding: const EdgeInsets.all(15.0),
                                      child: Row(
                                        mainAxisAlignment:
                                            MainAxisAlignment.spaceBetween,
                                        children: [
                                          const Text(
                                            'Total Due',
                                            style: TextStyle(fontSize: 18),
                                          ),
                                          Text(
                                            'R${cart.totalAmount.toStringAsFixed(2)}',
                                            style: const TextStyle(
                                                fontSize: 22,
                                                letterSpacing: 0.5,
                                                fontWeight: FontWeight.bold),
                                          ),
                                        ],
                                      ),
                                    ),
                                    ElevatedButton(
                                      child: const Center(
                                        child: Padding(
                                          padding: EdgeInsets.symmetric(
                                              vertical: 15.0),
                                          child: Text(
                                            'Process Order',
                                            style: TextStyle(
                                              color: Colors.white,
                                            ),
                                          ),
                                        ),
                                      ),
                                      onPressed: () async {
                                        try {
                                          setState(() {
                                            isLoading = true;
                                          });
                                          await FirebaseFirestore.instance
                                              .collection('orders')
                                              .add({
                                            'date': DateTime.now(),
                                            'order': cart.items.values
                                                .map((prod) =>
                                                    '${prod.title}, ${prod.quantity}')
                                                .join(";")
                                                .toString(),
                                            'total': cart.totalAmount
                                                .toStringAsFixed(2),
                                          });
                                          Navigator.of(context)
                                              .pushReplacementNamed(
                                                  OrderSuccess.routeName);

                                          setState(() {
                                            isLoading = false;
                                          });

                                          cart.clearCart();
                                        } on FirebaseException catch (e) {
                                          print(e.toString());
                                          setState(() {
                                            isLoading = false;
                                          });
                                        }
                                      },
                                    ),
                                    const SizedBox(
                                      height: 20.0,
                                    ),
                                  ],
                                );
                              }),
                        ],
                      ),
                    ),
                  ),
          );
  }
}

enter image description here

1 Answer 1

1

The null check operator is the ! you use to tell Dart that you are certain that the preceding variable is not null. If you're wrong (and it is null) you'll get this error. There are two places where you could get this error in your code.

In your code, you have final user = FirebaseAuth.instance.currentUser and it is not a given that this is not null, yet you use the null check operator in the statement .doc(user!.uid) which will throw the error if user is null.

Likewise, you set the variable doc using DocumentSnapshot? doc = snapshot.data (clearly a variable that can be null) and use the null check operator in title: Text(doc!['address']), which could also generate this error.

If you variable can be null, then you have to check for that possibility using an if... then construct or using null-aware operators like ? and ??. Only if you can statically prove that a nullable variable cannot ever be null at a certain point of your code can you forego that check and use the null-check operator !.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks @Bram, I've replaced all the null check operators with the null-aware operators. However I'm still getting the same error
If the error actually happens inside the Navigator.of(context)... statement (as your screenshot suggests) then perhaps you have not set up your MaterialApp above the widget correctly (the Navigator needs a Router, and a Router is created by a MaterialApp or a WidgetsApp).
I've just made sure that all my routes are properly configured. What is weird is that when I remove the isLoading ? LoadingSpinner condition around the scaffold its working. what could possible be the issue? @Bram
I suspect that is because without a Scaffold (when isLoading is true) the Router and therefore the Navigator is not set up properly.
@Bram Neither your answer nor your comments are providing any value rather than misleading the question asker.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.