Home > other >  Cant retrieve certain fields from the parsed list of the Firestore database
Cant retrieve certain fields from the parsed list of the Firestore database

Time:09-16

I am building a restaurant app in which I have used Firestore as my backend. I have stored the details of the menu in a collection Menu and each menu item in specific documents. Firstly, is that a good data model, or should I have the whole menu in the same document?

Secondly, the problem is while I retrieve the the collection and the docs, I am not being able to access some fields. If there are 4 documents and all of them contains the field 'Name' and data in the field. But when I fetch the data, parse it inot the list and have the command Menu[index]['Name] only two of the names in the documents are displayed while the other two return null.

class MenuController extends GetxController {
  final CollectionReference _menulsit =
      FirebaseFirestore.instance.collection('Menu');

  Future getmenu() async {
    List Menulist = [];
    try {
      await _menulsit.get().then((QuerySnapshot snapshot) {
        snapshot.docs.forEach((element) {
          Menulist.add(element.data());
        });
      });
      return Menulist;
    } catch (e) {
     
      return null;
    }
  }
}

While I parse it into a list and print the list, the data is retrieved and is printed in the console. There is the field 'Name' printed on the console but when I try to access it from the list it returns null. The same fields on some documents are returned but the same fields on some other documents are returned to be null.

I have used the list from the class, made a method, and provided a list here with the data retrieved. I need to use the data in a listview.seperated.

class _FoodmenuState extends State<Foodmenu> {
  List menulist = [];
  @override
  void initState() {
    super.initState();
    fetchmenu();
  }

  Future fetchmenu() async {
    dynamic resultmenu = await MenuController().getmenu();
    if (resultmenu == null) {
      return Text('Unable to retrive data');
    } else {
      setState(() {
        menulist = resultmenu;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      Container(
          height: 228,
          child: ListView.separated(
              scrollDirection: Axis.horizontal,
              itemBuilder: ((context, index) => _menucontent(index, menulist)),
              separatorBuilder: ((context, index) {
                return SizedBox(
                  width: 18,
                );
              }),
              itemCount: menulist.length))
    ]);
  }
}

While I print the list there is the field "Name" but I can't access it.

Print(menu)
I/flutter (31598): [{Name: Cheese Burger}, {Name : Buffalo Wings}, {Name : Pasta Bolognese }, {Name : Chicken MoMo}]

Print(menu[1])
I/flutter (31598): {Name : Buffalo Wings}

Print(menu[1]['Name']
I/flutter (31598): null

CodePudding user response:

Its better to store each menu item in separate document as it would enable to fetch only some menu items based on some conditions.

Regarding menu[1]['Name'] value printed as null:

As Print(menu) is giving correct JSON response, I think there is extra space after Name word in firestore document. You might have added this data manually :)

CodePudding user response:

First of all you should consider defining data types as it would lower chances of error and provide better suggestion if data types are mentioned. Make a class of MenuItem and make menu items as it might help when you want to add any item in overall app. Below is a example to help you understand.


class MenuItem {
  final String name;
  final int price;
  final String description;
  //you can add extra field here 
  MenuItem(
      {required this.name, required this.price, required this.description});
  MenuItem.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        price = json['price'],
        description = json['description'];
}

Future getmenu() async {
  List<MenuItem> menulist = [];
  try {
    await _menulsit.get().then((QuerySnapshot snapshot) {
      snapshot.docs.forEach((element) {
        menulist.add(MenuItem.fromJson(element.data()));
      });
    });
    return menulist;
  } catch (e) {
    return menulist;
  }
}

Now if you want to access name you can try like this menulist[0].name beside this if you type menulist[0]. it will give you suggestion whatever a menuItem can hold.

  • Related