arbiter
arbiter

Reputation: 451

Adding Multiple List Tile Items in Flutter to List

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:

enter image description here

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:

enter image description here

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

enter image description here

enter image description here

I am getting these errors in different files when I change these, even if I change the value of everything to Text.

enter image description here

Upvotes: 2

Views: 3811

Answers (1)

Heikkisorsa
Heikkisorsa

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

Related Questions