1

I have been stuck on the futureBuilder with the following error:

I/flutter ( 5307): NoSuchMethodError: Class '_JsonQuerySnapshot' has no instance method 'data'.
I/flutter ( 5307): Receiver: Instance of '_JsonQuerySnapshot'
I/flutter ( 5307): Tried calling: data()

I am trying to get the shop details with the future builder:

class Shop extends StatelessWidget {

Widget getProductsAndImages(BuildContext context) {
final outletId = ModalRoute.of(context)!.settings.arguments as String;
return StreamBuilder(
    stream: productsRef.doc(outletId).collection('products').snapshots(),
    builder: (BuildContext context, AsyncSnapshot snapshot) {
      if (!snapshot.hasData) {
        return Center(
          child: Text('Nothing found!'),
        );
      } else {
        List<String> productImgs = List.from(snapshot.data.get('productImageURL'));
            return ProductItem(
                productId: snapshot.data[productId],
                productName: snapshot.data[productName],
                productDescription: snapshot.data[prodDesc],
                productPrice: double.parse(
                  snapshot.data[productPrice].toString(),
                ),
                images: snapshot.data[productImgs][4],
                category: snapshot.data[category],
                count: double.parse(
                  snapshot.data[countInStock].toString(),
                ),
                outletId: outletId
            );
      }
    });
}

@override
Widget build(BuildContext context) {
final outletData = Provider.of<OutletData>(context);
final outletId = ModalRoute.of(context)!.settings.arguments as String;
print('outlet id--->>> $outletId');

return Scaffold(
    appBar: appHeader(context),
    backgroundColor: color2,
    extendBodyBehindAppBar: true,
    body:  Stack(
        children: <Widget>[
    Container(
    decoration: const BoxDecoration(
    image: DecorationImage(image: AssetImage("assets/images/background.jpg"),
  fit: BoxFit.cover,),
),
),
FutureBuilder(
      future: outletData.getOutletById(outletId),
      builder: (ctx, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting ||
            snapshot.data == null) {
          return
            Center(
              child: Text("Nothing found"),
            );
        }
        return snapshot.data.length == 0
            ? Center(
          child: Text("No products"),
        )
            : SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              ShopHeader(
                outletName: snapshot.data['outletName'],
                outletImage: snapshot.data['outletImageURL'],
                location: snapshot.data['location'],
                description: snapshot.data['description'],
                phoneNum: snapshot.data['phone'],
                merchantId: snapshot.data['merchantId'],
                outletId: outletId,
              ),
              Padding(
                padding: const EdgeInsets.all(15.0),
                child: Text(
                  "Recommended products:",
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 17,
                    color: Colors.black54,
                  ),
                ),
              ),
              ListView.builder(
                padding: EdgeInsets.zero,
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(),
                itemBuilder: (ctx, index) {
                  return
                    getProductsAndImages(context);                    
                },
              ),
            ],
          ),
        );
      },
    )
]));
}
}

getOutletDataById() method is as follows:

Future<Map<String, dynamic>> getOutletById(String outId) async {
var outletsById;
final Map<String, dynamic> idOutlet = {};
_outletMerchant.clear();
try {
  outletsById =
  await outletsCollectionRef.doc(outId).collection('products').get();
  var outletResponse = outletsById.data();

  var outletMerchantData = await firestore
      .collection(allUserCollection)
      .doc(outletResponse[merchantId])
      .get();

  var merchantResponse = outletMerchantData.data();
  print('outlet merchant data-->>> ${merchantResponse}');
  _outletMerchant.addAll(merchantResponse!);

  idOutlet.addAll(outletResponse);

} catch (err) {
  print(err);
}
return idOutlet;
}

why is it giving me the above error? I tried using snapshot.data()['outletName'] but the error is the same. Please, help me. I am new and just learning flutter. Thanks!

HaKim
  • 277
  • 2
  • 12

1 Answers1

2

Looks like the problem here is in getOutletById method.

outletsById = await outletsCollectionRef.doc(outId).collection('products').get();
var outletResponse = outletsById.data();

Here outletsById has type QuerySnapshot or specifically _JsonQuerySnapshot that represents a set of documents.

You need to select a specific document from QuerySnapshot#docs (e.g. var outletResponse = outletsById.docs[0].data())