List<dynamic> is not a subtype fo type List<Itemshop> of function result

Viewed 45

Hello guys I face this problem when I Create a Search Delegate in a flutter I try to call data from Firebase and add it in List Class but it shows me this error

List<dynamic> is not a subtype fo type List<Itemshop> of function result

Problem Here

  List<ItemShop> ItemShopList = [];
  CollectionReference ItemShopRef =
      FirebaseFirestore.instance.collection('ItemShop');
  List filterItemShop = [];
  int counter = 0;
  Future getData() async {
    var responsce = await ItemShopRef.get();
    responsce.docs.forEach((element) {
      ItemShop itemShop = ItemShop(element["ItemCatgore"], element["ItemImage"],
          element["ItemKG"], element['ItemName'], element["ItemPrice"]);

      if (counter == 0) {
        ItemShopList.add(itemShop);
      }
    });
    print(ItemShopList);
    return ItemShopList;
  }

Class for ItemShop

class ItemShop {
  final String ItemCatgore, ItemImage, ItemKG, ItemName;
  int ItemPrice;
  ItemShop(this.ItemCatgore, this.ItemImage, this.ItemKG, this.ItemName,
      this.ItemPrice);
}

Full Code:

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

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

  @override
  State<SearchPage> createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Color.fromARGB(255, 184, 132, 132),
        actions: [
          IconButton(
              onPressed: () {
                showSearch(context: context, delegate: mySearch());
              },
              icon: Icon(Icons.search))
        ],
      ),
    );
  }
}

class mySearch extends SearchDelegate {
  List<ItemShop> ItemShopList = [];
  CollectionReference ItemShopRef =
      FirebaseFirestore.instance.collection('ItemShop');
  List filterItemShop = [];
  int counter = 0;
  Future getData() async {
    var responsce = await ItemShopRef.get();
    responsce.docs.forEach((element) {
      ItemShop itemShop = ItemShop(element["ItemCatgore"], element["ItemImage"],
          element["ItemKG"], element['ItemName'], element["ItemPrice"]);

      if (counter == 0) {
        ItemShopList.add(itemShop);
      }
    });
    print(ItemShopList);
    return ItemShopList;
  }

  ////////////////////////////////////////////////
  @override
  List<Widget>? buildActions(BuildContext context) {
    return [
      IconButton(
          onPressed: () {
            query = "";
          },
          icon: Icon(Icons.close))
    ];
  }

  @override
  Widget? buildLeading(BuildContext context) {
    return IconButton(
        onPressed: () {
          close(context, null);
        },
        icon: Icon(Icons.arrow_back));
  }

  @override
  Widget buildResults(BuildContext context) {
    return FutureBuilder(
        future: getData(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.data == null) {
            return Center(
              child: CircularProgressIndicator(),
            );
          } else {
            return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int i) {
                  return snapshot.data[i].ItemName == query
                      ? Card(
                          child: Column(
                            children: [
                              Container(
                                color: Colors.grey[200],
                                height: 150,
                                width: double.infinity,
                                child: Text(
                                  snapshot.data[i].ItemName,
                                  textAlign: TextAlign.center,
                                  style: TextStyle(fontSize: 35),
                                ),
                              ),
                              Container(
                                child: Text(snapshot.data[i].ItemName),
                              )
                            ],
                          ),
                        )
                      : Container();
                });
          }
        });
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    filterItemShop = ItemShopList.where((element) =>
        element.ItemName.toLowerCase().contains(query.toLowerCase())).toList();

    return FutureBuilder(
        future: getData(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.data == null) {
            return Center(
              child: CircularProgressIndicator(),
            );
          } else {
            return ListView.builder(
                itemCount:
                    query == "" ? snapshot.data.length : filterItemShop.length,
                itemBuilder: (BuildContext context, int i) {
                  return InkWell(
                    onTap: () {
                      query = query == ""
                          ? ItemShopList[i].ItemName
                          : filterItemShop[i].ItemName;

                      showResults(context);
                    },
                    child: Card(
                      child: query == ""
                          ? ListTile(
                              leading: Text(snapshot.data[i].ItemName),
                              title: Text(snapshot.data[i].ItemName),
                              subtitle: Text(snapshot.data[i].ItemName),
                            )
                          : ListTile(
                              leading: Text(filterItemShop[i].ItemName),
                              title: Text(filterItemShop[i].ItemName),
                              subtitle: Text(filterItemShop[i].ItemName),
                            ),
                    ),
                  );
                });
          }
        });
  }
}

class ItemShop {
  final String ItemCatgore, ItemImage, ItemKG, ItemName;
  int ItemPrice;
  ItemShop(this.ItemCatgore, this.ItemImage, this.ItemKG, this.ItemName,
      this.ItemPrice);
}
2 Answers

there, I think the better approach is not for each but map. and use type defines variable so you will not get type error as long as you do not use casting method. final List<Itemshop> x = responsce.docs.map((e)=>Itemshop.fromMap(e.data()..docId = e.id)).toList(); return x; ypu can also just retun the map fucntion like return responsce.docs.map((e)=> ....

Itemshop should be ItemShop, standard dart format.

Itemshop.fromMap is a function that you build in Itemshop class. data classes always have this kind of helper. fromMap, toMap, fromJson, toJson. a lot of code generation in the dart for this if you don't want to write it yourself.

For example for your comment,

import 'dart:convert';

class ItemShop {
  final String? itemCatgore;
  final String? itemImage;
  final String? ItemKG;
  final String? ItemName;
  final String? ItemPrice;

  ItemShop({
    this.itemCatgore,
    this.itemImage,
    this.ItemKG,
    this.ItemName,
    this.ItemPrice,
  });

  Map<String, dynamic> toMap() {
    return {
      'itemCatgore': itemCatgore,
      'itemImage': itemImage,
      'ItemKG': ItemKG,
      'ItemName': ItemName,
      'ItemPrice': ItemPrice,
    };
  }

  factory ItemShop.fromMap(Map<String, dynamic> map) {
    return ItemShop(
      itemCatgore: map['itemCatgore'],
      itemImage: map['itemImage'],
      ItemKG: map['ItemKG'],
      ItemName: map['ItemName'],
      ItemPrice: map['ItemPrice'],
    );
  }

  String toJson() => json.encode(toMap());

  factory ItemShop.fromJson(String source) =>
      ItemShop.fromMap(json.decode(source));

  ItemShop copyWith({
    String? itemCatgore,
    String? itemImage,
    String? ItemKG,
    String? ItemName,
    String? ItemPrice,
  }) {
    return ItemShop(
      itemCatgore: itemCatgore ?? this.itemCatgore,
      itemImage: itemImage ?? this.itemImage,
      ItemKG: ItemKG ?? this.ItemKG,
      ItemName: ItemName ?? this.ItemName,
      ItemPrice: ItemPrice ?? this.ItemPrice,
    );
  }

  @override
  String toString() {
    return 'ItemShop(itemCatgore: $itemCatgore, itemImage: $itemImage, ItemKG: $ItemKG, ItemName: $ItemName, ItemPrice: $ItemPrice)';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is ItemShop &&
        other.itemCatgore == itemCatgore &&
        other.itemImage == itemImage &&
        other.ItemKG == ItemKG &&
        other.ItemName == ItemName &&
        other.ItemPrice == ItemPrice;
  }

  @override
  int get hashCode {
    return itemCatgore.hashCode ^
        itemImage.hashCode ^
        ItemKG.hashCode ^
        ItemName.hashCode ^
        ItemPrice.hashCode;
  }
}

plus dart use camel case for all the variable and function (first latest is small later, second-word first letter is capital)

and all words first capital letter

Specify the type of future in futurebuilder, here it is list itemshop as shown below.

return FutureBuilder<List<ItemShop>>(
            //TODO: YOUR CODE
           );
Related