问题
I have this form that is filled out and then when submitted, it makes a separate List Tile in List View in Nosql. Here is the part where I make the 'food' item and on 'submit' button clicked, it makes the item and sends it to list view on the next screen. Notice how each food item has a uniqueID which is Uuid random string.
class FoodForm extends StatefulWidget {
final Food food;
final int foodIndex;
FoodForm({this.food, this.foodIndex});
@override
State<StatefulWidget> createState() {
return FoodFormState();
}
}
class FoodFormState extends State<FoodForm> {
String _name;
String _calories;
String _uniqueID = Uuid().v4().toString();
@override
void initState() {
super.initState();
if (widget.food != null) {
_name = widget.food.name;
_calories = widget.food.calories;
_uniqueID = widget.food.uniqueID;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
// resizeToAvoidBottomInset: false,
appBar: AppBar(title: Text("Food Form")),
body: SingleChildScrollView(
child: Container(
margin: EdgeInsets.all(24),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildName(),
_buildCalories(),
SizedBox(height: 20),
widget.food == null
? RaisedButton(
child: Text(
'Submit',
style: TextStyle(color: Colors.blue, fontSize: 16),
),
onPressed: () {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
Food food = Food(
name: _name,
calories: _calories,
//unique id not used for some reason
uniqueID: _uniqueID,
);
DatabaseProvider.db.insert(food).then(
(storedFood) =>
BlocProvider.of<FoodBloc>(context).add(
AddFood(storedFood),
),
);
Navigator.pop(context);
//IT PRINTS UNIQUE ID OF EACH FOOD MADE AND STORED IN DATABASE
print(_uniqueID);
}
Here is the Food class with its builders:
class Food {
int id;
String name;
String calories;
String uniqueID;
Food(
{this.id,
this.name,
this.calories,
this.uniqueID});
In the next page, here's the code that should send the strings from that Food to another 'cart' page. It works when each separate item is send:
return ListTile(
trailing: Container(
padding:
EdgeInsets.only(top: 15.0),
child: IconButton(
icon: Icon(Icons.add),
onPressed: () => model.addCartItem( "${food.name}, Calories: ${food.calories}"),
key: Key(food.uniqueID)))
I have added the key as the food.uniqueID which should be the uuid that is made randomly each time the food item is created, and it is, I printed it out and it is indeed unique. Here is the 'addCartItem' code, which is Provider from another screen:
class CartItemsModel extends ChangeNotifier {
List<String> _cartItems = [];
List<String> get cartItems => _cartItems;
addCartItem(String item) {
_cartItems.add(item);
notifyListeners();
}
deleteCartItem(String item) {
_cartItems.remove(item);
notifyListeners();
}
}
And here is the final 'cart' screen where all these items sent from previous code from 'addCartItem' function on pressed go:
class _CartState extends State<Cart> {
@override
Widget build(BuildContext context) {
return Consumer<CartItemsModel>(
builder: (c, model, _) => Scaffold(
appBar: AppBar(
title: Text('Cart'),
centerTitle: true,
),
body: SingleChildScrollView(
child: Column(
the list
children: model
.cartItems
.map((e) => Dismissible(
onDismissed: (direction) {
setState(() {
model.deleteCartItem(e);
});
},
background: Container(color: Colors.white),
key: Key(e),
child: Card(
child: ListTile(
title: Text(e, style: TextStyle(fontSize: 30.0)),
trailing: Container(
padding: EdgeInsets.only(top: 15),
child: IconButton(
icon: Icon(Icons.delete),
onPressed: () {
setState(() {
model.deleteCartItem(e);
});})))))).toList()))));}}
I don't think this is the best solution to the method, but it works when I add each separate item made. The issue I get is that when I click the same List Tile item twice to be added I get the 'duplicate keys found' error when I go to 'cart' item (previous code).
I have tried many things, but I still get the error. Without it, the code works fine (if someone has a better method, such as maybe not taking Strings in food class, let me know).
I understand that it says that there are duplicate keys on the List, but each item has a unique Uuid, so I am not sure where I am wrong. I know it's a lot of code, but let me know if you need anything else, this is probably a simple solution, but it has been an issue to me a lot. I have temporarily 'fixed' it like this:
model.addCartItem("${name.name}\n${name.calories}${Uuid().v4()}")
but it gives an ugly string of Uuid on the 'cart' page in each food list tile item. I need it to work like that, but without the ugly string.
UPDATE
I still get these errors when I add the code that should fix it:
Still getting duplicate keys error with this code:
I have temporatily 'fixed' the issue adding the random uuid to the string passed, but it adds an ugly string to the 'cart' window, I don't want it to show.
来源:https://stackoverflow.com/questions/65112068/duplicate-keys-error-in-flutter-list-view