Search code examples
flutterdartproviderriverpod

Existing state editing in Riverpod / Flutter


How I can manipulate the existing state in Riverpod. 'm a beginner about Flutter and Riverpod. When I try add one to Order error pops up and says:

Error: A value of type 'int' can't be assigned to a variable of type 'List'.

final OrderPaperProvider = StateNotifierProvider<OrderPaper, List<Order>>((ref) {
  return OrderPaper();
});

@immutable
class Order {
  final String product_id;
  final String product_name;
  final int product_price;
  final int product_count;

  Order({required this.product_id, required this.product_name, required this.product_price, required this.product_count});

  Order copyWith({product_id, product_name, product_price, product_count}) {
    return Order(
      product_id: product_id,
      product_name: product_name,
      product_price: product_price,
      product_count: product_count,
    );
  }
}

class OrderPaper extends StateNotifier<List<Order>> {
  OrderPaper() : super([]);

  void addOrder(Order order) {
    for (var x = 0; x < state.length; x++) {
      if (state[x].product_id == order.product_id) {
        addOneToExistingOrder(x, order);
        return;
      }
    }
    state = [...state, order];
  }

  void removeOrder(String product_id) {
    state = [
      for (final order in state)
        if (order.product_id != order) order,
    ];
  }

  void addOneToExistingOrder(index, Order order) {
    state = state[index].product_count + 1; // <--------- Error in this line
  }

  void clearOrderPaper() {
    state = [];
  }
}

Solution

  • What is happening in the code you posted is basically this:

    • You are telling it to update the state which is a List<Order> with an integer.

    • This is because state[index].product_count + 1 actually equals a number, for example 1+2 = 3.

    • So you are telling it, state = 3, and this causes your error.

    What you need to do, is create a new state with the list of items and the edited item, like this (you don't need to pass the index, you can get it in the function):

     void addOrder(Order order) {
    //find if the product is in the list. The index will not be -1.
     final index = state.indexWhere((entry) => entry.product_count == order. product_count);
    
        if (index != -1) {
          //if the item is in the list, we just edit the count
          state = [
            ...state.sublist(0, index),
            order.copyWith(product_count: state[index].product_count + 1),
            ...state.sublist(index + 1),
          ];  
        }else {
           //otherwise, just add it as a new entry.
          state = [...state, order],
         }
        
    }