2

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

8
  • I can post full code if someone needs it, I really need to solve this, I tried many different things, not sure how to fix it easily. Commented Nov 30, 2020 at 10:20
  • Are you even setting the Key property in the ListTile widget? Commented Nov 30, 2020 at 10:42
  • BTW, formatting your code correctly helps others reading and understanding it faster. Commented Nov 30, 2020 at 10:44
  • In your update, you did not wrap your string into a Text widget as I proposed in my answer. Additionally, try to use UniqueKey() if the ValueKey does not want to work. Commented Dec 2, 2020 at 16:41
  • Thanks, I am pretty new to coding in general, so it's a bit confusing, but I am getting to understand it more and more. Any idea how I would change the _CartState to accept the Text instead of string? Commented Dec 2, 2020 at 18:33

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I am gettin the Instance member 'uniqueID' can't be accessed using static access error, I understand that it can't access it because the value is random each time, how would I fix that? Also not sure how I would adjust the items in the _CartState since they are now text, sorry I'm a bit new to coding in general, this is just practice.
It isn't static because it is String _uniqueID = Uuid().v4(); in the Food class

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.