Home > Software design >  Error Null value on Dependent DropdownButtons
Error Null value on Dependent DropdownButtons

Time:01-11

I'm creating a dependent dropdownbuttons using StreamBuilder. Until now, I created three dropdownbuttons with the information showing correctly. But I get a error when I want to change the value of a higher level dropdownbutton once the process of the three dropdownbuttons showing the info in a hierachical way is done, saying this:

type Null isn't a subtype of Map<dynamic,dynamic>

This error is showed in the third StreamBuilder, specifically in this line:

final data = Map<String, dynamic>.from(
                                  (snapshot.data!.snapshot.value as Map));

Here's the code:

import 'dart:async';

import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';

class NewCauseMenu extends StatefulWidget {
  String? area;
  NewCauseMenu(this.area, {super.key});

  @override
  State<NewCauseMenu> createState() => _NewCauseMenuState();
}

class _NewCauseMenuState extends State<NewCauseMenu> {
  final db = FirebaseDatabase.instance;

  String? dropdownValue;
  String? problem;
  String? causa1;
  String? causa2;
  String? causa3;
  String? causa4;

  var setDefaultProblem = true,
      setDefaultCauseOne = true,
      setDefaultCauseTwo = true;
  @override
  Widget build(BuildContext context) {
    final myRef = db.ref();

    return WillPopScope(
      onWillPop: () {
        return _onWillPopScope();
      },
      child: SafeArea(
          child: Scaffold(
        appBar: AppBar(
          title: Text('Menú Nueva Causa ${widget.area}'),
        ),
        body: Center(
          child: Column(
            children: [
              const SizedBox(
                height: 25,
              ),
              SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    const SizedBox(
                      width: 25,
                    ),
                    StreamBuilder(
                        stream: myRef.child(widget.area.toString()).onValue,
                        builder: (context, snapshot) {
                          if (!snapshot.hasData) return Container();
                          final data = Map<String, dynamic>.from(
                              (snapshot.data)!.snapshot.value as Map);
                          if (setDefaultProblem) {
                            problem = data.keys.first.toString();
                          }
                          return DropdownButton(
                            value: problem,
                            icon: const Icon(Icons.arrow_downward),
                            isExpanded: false,
                            elevation: 16,
                            underline: Container(
                              height: 2,
                              color: Colors.blueAccent,
                            ),
                            items: data.keys.map(((e) {
                              return DropdownMenuItem(
                                  value: e.toString(),
                                  child: Text(e.toString()));
                            })).toList(),
                            onChanged: (value) {
                              setState(() {
                                problem = value!;
                                setDefaultProblem = false;
                                setDefaultCauseOne = true;
                              });
                            },
                          );
                        }),
                    const SizedBox(
                      width: 25,
                    ),
                    ElevatedButton(
                      onPressed: () {},
                      style: ElevatedButton.styleFrom(
                          backgroundColor: Colors.blue),
                      child: const Text('Editar'),
                    ),
                    const SizedBox(
                      width: 25,
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 25,
              ),
              problem != null
                  ? SingleChildScrollView(
                      scrollDirection: Axis.horizontal,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: [
                          const SizedBox(
                            width: 25,
                          ),
                          StreamBuilder(
                            stream: myRef
                                .child(widget.area.toString())
                                .child(problem.toString())
                                .onValue,
                            builder: (context, snapshot) {
                              if (!snapshot.hasData || snapshot.data == null) {
                                return const Text(
                                    'Aquí aparecerá las causas del problema seleccionado.');
                              }
                              final data = Map<String, dynamic>.from(
                                  (snapshot.data!.snapshot.value as Map));
                              if (setDefaultCauseOne) {
                                causa1 = data.keys.first.toString();
                              }
                              return DropdownButton(
                                value: causa1,
                                icon: const Icon(Icons.arrow_downward),
                                isExpanded: false,
                                elevation: 16,
                                underline: Container(
                                  height: 2,
                                  color: Colors.blueAccent,
                                ),
                                items: data.keys.map(((e) {
                                  return DropdownMenuItem(
                                      value: e.toString(),
                                      child: Text(e.toString()));
                                })).toList(),
                                onChanged: (value) {
                                  setState(() {
                                    causa1 = value!;
                                    setDefaultCauseOne = false;
                                    setDefaultCauseTwo = true;
                                  });
                                },
                              );
                            },
                          ),
                          const SizedBox(
                            width: 25,
                          ),
                          ElevatedButton(
                            onPressed: () {},
                            style: ElevatedButton.styleFrom(
                                backgroundColor: Colors.blue),
                            child: const Text('Editar'),
                          ),
                          const SizedBox(
                            width: 25,
                          ),
                        ],
                      ),
                    )
                  : const Text(
                      'Aquí aparecerá las causas del problema seleccionado.'),
              const SizedBox(
                height: 25,
              ),
              causa1 != null || problem != null
                  ? Row(
                      mainAxisSize: MainAxisSize.min,
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        const SizedBox(
                          width: 25,
                        ),
                        StreamBuilder(
                            stream: myRef
                                .child(widget.area.toString())
                                .child(problem.toString())
                                .child(causa1.toString())
                                .onValue,
                            builder: (context, snapshot) {
                              if (!snapshot.hasData || snapshot.data == null) {
                                return const Text(
                                    'Aquí aparecerá las subcausas del problema seleccionado.');
                              }
                              final data = Map<String, dynamic>.from(
                                  (snapshot.data!.snapshot.value as Map));
                              if (setDefaultCauseTwo) {
                                causa2 = data.keys.first.toString();
                              }
                              return Flexible(
                                fit: FlexFit.loose,
                                child: DropdownButton(
                                  value: causa2,
                                  icon: const Icon(Icons.arrow_downward),
                                  isExpanded: true,
                                  elevation: 16,
                                  itemHeight: null,
                                  underline: Container(
                                    height: 2,
                                    color: Colors.blueAccent,
                                  ),
                                  items: data.keys.map(((e) {
                                    return DropdownMenuItem(
                                        value: e.toString(),
                                        child: Text(
                                          e.toString(),
                                        ));
                                  })).toList(),
                                  onChanged: (value) {
                                    setState(() {
                                      causa2 = value!;
                                      setDefaultCauseTwo = false;
                                    });
                                  },
                                ),
                              );
                            }),
                        const SizedBox(
                          width: 25,
                        ),
                        ElevatedButton(
                          onPressed: () {},
                          style: ElevatedButton.styleFrom(
                              backgroundColor: Colors.blue),
                          child: const Text('Editar'),
                        ),
                        const SizedBox(
                          width: 25,
                        )
                      ],
                    )
                  : const Text(
                      'Aquí aparecerá las subcausas del problema seleccionado.'),
            ],
          ),
        ),
      )),
    );
  }

  Future<bool> _onWillPopScope() async {
    Navigator.of(context).pop();
    return false;
  }
}

I don't know why I get this error if the values of the others StreamBuilders are not Null. Help me, please.

CodePudding user response:

Problem:

From the error message, you're casting a null value, snapshot.data!.snapshot.value, to a Map.

The value property of a Firebase Realtime Database DataSnapshot is nullable.

Solution:

Add a null check for snapshot.data!.snapshot.value where you check for null data.

Change:

if (!snapshot.hasData || snapshot.data == null) {
  return const Text('Aquí aparecerá las causas del problema seleccionado.');
}

final data = Map<String, dynamic>.from(snapshot.data!.snapshot.value as Map));

to:

if (!snapshot.hasData || snapshot.data == null || snapshot.data!.snapshot.value == null) {
  return const Text('Aquí aparecerá las causas del problema seleccionado.');
}

final data = Map<String, dynamic>.from(snapshot.data!.snapshot.value as Map));
  • Related