Reputation: 451
I have this code that I can't get to work properly. I have a Food class and I have initialized the name, price, and unique ID strings on it. I made the unique ID to be Uuid().v4(), which would give each food item a random string.
FOOD CLASS
class Food {
String name;
String price;
String uniqueID = Uuid().v4();
Food({this.name,
this.price,
this.uniqueID})}
On another page I have a Provider function that would add items in the cart, it is a list of string items (this may not be the best option). Here is the code for it:
class CartItemsModel extends ChangeNotifier {
List<String> _cartItems = [];
List<String> get cartItems => _cartItems;
addCartItem(String item) {
_cartItems.add(item);
notifyListeners();
}
Now, on another page, I am calling that food to be added to the cart, it is an icon with onPressed above function:
return ListTile(
trailing: Container(
padding:
EdgeInsets.only(top: 15.0),
child: IconButton(
icon: Icon(Icons.add),
onPressed: () =>
model.addCartItem(
"${food.name}, Calories: ${food.calories} ${food.price} din\nVegan: ${food.isVegan}, ${Uuid().v4()}")),
Now, you see that I have Uuid on there (without my uniqueID from Food class, because for some reason it doesn't work). I have the Uuid, so that there isn't an error with multiple duplicate items if the button would be clicked twice, here's the error without it:
The issue is that this works and is functional, but I have this ugly ID from the Uuid displayed on the final 'cart' window. Basically I want this ID to be invisible. Here is how it looks:
And here is the code for the 'cart' screen:
class _CartState extends State<Cart> {
@override
Widget build(BuildContext context) {
return Consumer<CartItemsModel>(
builder: (c, model, _) => Scaffold(
body: SingleChildScrollView(
child: Column(
//on trailing i should have icon with clear function that will delete that item from the list
children: model
.cartItems //maybe below can return ListView.separated like on the food list user, we'll see
.map((e) =>
So to keep long story short, my uniqueID isn't used on here because for some reason it doesn't make each list tile item unique with its key, so it doesn't display and give me error when clicked twice, that's why temporatily I am using the Uuid trick.
What I want is for this to work exactly like this, but without the ugly Uuid string to be seen. Is there simple I can do with it, maybe add something to the CartItemsModel code, a conditional, or something else?
If I change the code in onPressed to this:
onPressed: () {
if (!model.cartItems
.contains(food)) {
model.addCartItem(Food);
}
}
I am getting error:
The argument type 'Type' can't be assigned to the parameter type 'String
Is there a simple solution to have items added to the 'cart' screen easily, no matter how many times I click on the same item, just have each as a separate list tile in the cart screen?
UPDATE ERRORS
I am getting these errors in different files when I change these, even if I change the value of everything to Text.
Upvotes: 2
Views: 3811
Reputation: 905
Strings do not have a key property as far as I know. Try something like this (you could also use UniqueKey()) in order to get a key for your CardItems:
return ListTile(
trailing: Container(
padding: EdgeInsets.only(top: 15.0),
child: IconButton(
icon: Icon(Icons.add),
onPressed: () => model.addCartItem(
Text("${food.name}, Calories: ${food.calories} ${food.price} din\n
Vegan: ${food.isVegan}",
key:ValueKey(Food.uniqueID.toString()),
),
),
),
),
),
Then you need to adjust your CartItems model to List<Text> _cartItems = [];
and List<Text> get cartItems => _cartItems;
This way each element of the list has your unique key. Also you need to adjust the map function in your _CartState
builder because now you don't have Strings anymore but Text widgets.
Upvotes: 1