i created a simple function that add product to cart with buttons to add/reduce product quantity,unfortunately product quantity does not changes as add/reduce button is hit.it changes after some refresh.also the product is not added to cart.please help me identify the problem
These are codes.
productmodel class
class ProductModel {
int? id;
int qty=1;
String? product_name;
String? product_description;
int? product_price;
String? images;
ProductModel({this.id,required this.qty, this.product_name, this.product_description, this.product_price, this.images});
ProductModel.fromJson(Map<String, dynamic> json) {
id = int.tryParse(json['id']);
product_name = json['product_name'];
product_description = json['product_description'];
product_price = int.tryParse(json['product_price']);
images = json['images'];
qty=json[1]??1;
}
}
this is StateNotifier class
import 'package:five_star/ProductModel.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class Productstore extends StateNotifier<List<ProductModel>>{
Productstore(): super([]);
List<ProductModel> _carts=[];
List<ProductModel> get carts=> _carts;
void addToCart(ProductModel product) {
if (carts.contains(product)) {
product.qty++;
} else {
carts.add(product);
}
}
void removeFromCart(ProductModel product) {
carts.remove(product);
}
void removeCartqty(ProductModel product) {
if (product.qty == 1) {
carts.remove(product);
} else if (product.qty > 1) {
product.qty--;
}
}
void addCartqty(ProductModel product) {
product.qty++;
}
}
This is product detail class where i call addtocart function with functions to +/- product quantity.
import 'package:five_star/Cart.dart';
import 'package:five_star/ProductModel.dart';
import 'package:five_star/ProductStore.dart';
import 'package:five_star/all_products.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:five_star/home.dart';
final cartprovider=StateNotifierProvider<Productstore,List<ProductModel>>((ref)=>Productstore());
class product_detail extends ConsumerStatefulWidget {
const product_detail({super.key});
@override
product_detailState createState() => product_detailState();
}
class product_detailState extends ConsumerState<product_detail> {
@override
Widget build(BuildContext context) {
final product = ModalRoute.of(context)!.settings.arguments as ProductModel;
final cartnotifier=ref.watch(cartprovider.notifier);
final cartNotifier = ref.read(cartprovider.notifier);
return Scaffold(
appBar: AppBar(
title: const Text('PRODUCT DETAIL'),
backgroundColor: Colors.orange,
),
body: ListView(
children: [
Container(
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: Column(
children: [
Padding(
padding: EdgeInsets.all(10.0),
child: Container(
height: 160,
width: double.infinity,
child: (
Card(
color: Colors.white,
child: Image.network("https://hometronix.co.tz/admin/images/products/"+product.images.toString()),
)
),
//BoxDecoration(border: Border.all(color: Colors.black)),
),
),
Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Container(
child: Text(
product.product_name.toString(),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
),
),
Center(
child: Padding(
padding: EdgeInsets.all(4.0),
child: Text(
product.product_price.toString(),
style: TextStyle(color: Colors.black, fontSize: 20),
),
),
),
Padding(
padding: EdgeInsets.all(10.0),
child: Container(
height: 200,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(),
child: Center(
child: Text( product.product_description.toString())),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
height: 50,
width: MediaQuery.of(context).size.width / 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: () {
cartNotifier.removeCartqty(product);
},
icon: const Icon(
Icons.remove,
color: Colors.red,
)),
Text(
product.qty.toString(),
style: TextStyle(color: Colors.black),
),
IconButton(
onPressed: () {
cartNotifier.addCartqty(product);
},
icon: const Icon(
Icons.add,
color: Colors.green,
)),
],
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
height: 50,
width: MediaQuery.of(context).size.width / 2,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
foregroundColor: Colors.black,
),
onPressed: () {
cartNotifier.addToCart(product);
},
child: const Text(
'add to cart',
style: TextStyle(color: Colors.white),
),
),
),
),
],
),
)
],
),
);
}
}
2
Answers
You should use
ref.watch(cartprovider);
instead of usingref.watch(cartprovider.notifier);
There are several problems with the class
Productstore
. The state of theStateNotifier<List<ProductModel>>
is stored in the super constructor and it makes no sense to have the list:Instead you should have something similar to:
*) See riverpod documentation regarding StateNotifier.
Like choykarl mentioned, you are supposed to watch
cartprovider
instead of its notifier.Lastly, the documentation recommends migrating from
StateNotifier
toNotifierProvider
see migration from StateNotifier.