I have a question about this error that I have in my code. So, the app should show a list of products read from firebase. This is the code placed in the screen where I want to show Products:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'productWidget.dart';
import 'product.dart';
class ColinaMenu extends StatefulWidget {
const ColinaMenu({Key? key}) : super(key: key);
@override
State<ColinaMenu> createState() => _ColinaMenuState();
}
class _ColinaMenuState extends State<ColinaMenu> {
Future<List<String>> getDocId() async {
final snapshot = await FirebaseFirestore.instance.collection('produse').get();
final docIDs = snapshot.docs.map((doc) => doc.id).toList();
print('Number of products found: ${docIDs.length}');
print('Product IDs found: $docIDs');
return docIDs;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Meniu Colina'),
),
body: SafeArea(
child: FutureBuilder<List<String>>(
future: getDocId(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
final docIDs = snapshot.data!;
return Container(
height: MediaQuery.of(context).size.height,
child: ListView.builder(
itemCount: docIDs.length,
itemBuilder: (BuildContext context, int index) {
final product = GetProducts(docIDs[index]).product;
print('Product name: ${product.name}');
return widgetProduct(product: product);
},
),
);
}
},
),
),
);
}
}
Next we have the code for Product and getProducts classes:
import 'package:cloud_firestore/cloud_firestore.dart';
class Product {
late String name;
late String price;
late bool active;
late String id;
Product({
required this.name,
required this.price,
required this.active, required String id,
});
}
class GetProducts {
final String docID;
late Product product;
GetProducts(this.docID) {
FirebaseFirestore.instance.collection('produse').doc(docID).snapshots().listen((snapshot) {
product = Product(
id: snapshot.id,
name: snapshot['name'],
price: snapshot['price'],
active: snapshot['active'],
);
});
}
}
And finally the code for widgetProduct class where I designed how a product should be showed in the screen:
import 'package:flutter/material.dart';
import 'package:udelivery/product.dart';
import 'theme_data.dart';
class widgetProduct extends StatefulWidget {
Product product;
widgetProduct({
Key? key,
required this.product
}) : super(key: key);
@override
State<widgetProduct> createState() => _widgetProductState();
}
class _widgetProductState extends State<widgetProduct> {
var qty = ['1', '2', '3', '4'];
late String _selectedValue=qty[1];
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.fromLTRB(0, 15, 0, 0),
padding: const EdgeInsets.fromLTRB(10, 5, 5, 5),
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(10),
boxShadow: const [
BoxShadow(
spreadRadius: 1,
blurRadius: 5,
offset: Offset(0, 1), // changes position of shadow
),
]),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
flex: 6,
child: Text(
widget.product.name,
style: TextStyle(
color: MyTheme.textColor(context),
),
),
),
Expanded(
flex: 1,
child: DropdownButton(
value: _selectedValue,
items: qty.map(
(e){
return DropdownMenuItem(value: e, child: Text(e, style: TextStyle(color: MyTheme.textColor(context)),),);
}
).toList(),
onChanged: (val){
setState(() {
_selectedValue = val as String;
});
},
)
),
Expanded(
flex: 1,
child: IconButton(
onPressed: () {},
icon: Icon(
Icons.add_circle_rounded,
color: MyTheme.buttonColor(context),
))),
],
),
Row(children: [
Text(
'${widget.product.price} lei',
style: TextStyle(
color: MyTheme.buttonColor(context),
),
),
]),
],
),
);
}
}
When I run the app, after a few secconds when CircularProgresIndicator is loading, I recieve this error: "LateInitializationError: Field ‘product’ has not been initialized.". How can I fix that error?
3
Answers
Currently, you have declared
product
aslate
and it is only assigned a value inside the listen callback of the stream. This means that it might not have been initialized by the time you try to use it.You can remove the
late
keyword and initialize theproduct
variable to a default value.Or, you can use a completer to return the value once it’s ready:
Use it like this:
You are using
late
keyword and assigning the value at the same time.Try assigning the value in initState
Instead of declaring Product like this:
declare it like this: