Mahi
Mahi

Reputation: 1752

Provider not getting data from database

I was trying to make a simple cart app which loads cart data from database. actually loads data from database to provider. but when we add item to cart and close the app, when It comes back cart hasn't any item.

fetchCartProducts called to get data from database, it must give to the provider cartItems. but it stores data in database, not showing it when it's closed.

home_screen.dart

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  Future<List<FoodItem>> _foodItems;

  @override
  void initState() {
    super.initState();
    _foodItems = ApiService.getFoodItems();
    Provider.of<CartProvider>(context, listen: false).fetchCartProducts();
  }

  @override
  Widget build(BuildContext context) {
    final cart = Provider.of<CartProvider>(context, listen: false);

    return Scaffold(
      appBar: AppBar(
        title: const Text('Food Cart'),
        actions: [
          Consumer<CartProvider>(
            builder: (_, cartprovider, ch) => Badge(
              child: ch,
              value: cartprovider.itemCount.toString(),
            ),
            child: IconButton(
              icon: Icon(Icons.shopping_cart),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (_) {
                    return CartScreen();
                  }),
                );
              },
            ),
          ),
        ],
      ),
      body: FutureBuilder<List<FoodItem>>(
        future: _foodItems,
        builder: (conext, snapshot) => !snapshot.hasData
            ? const Center(
                child: CircularProgressIndicator(),
              )
            : ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) {
                  FoodItem foodItem = snapshot.data[index];
                  return ListTile(
                    title: Text(foodItem.productName),
                    subtitle: Text(foodItem.variant),
                    trailing: IconButton(
                      onPressed: () {
                        cart.addToCart(
                          foodItem.storeid.toString(),
                          foodItem.productName,
                          1,
                          foodItem.price,
                        );
                        setState(() {});
                      },
                      icon: const Icon(Icons.shopping_cart),
                    ),
                  );
                },
              ),
      ),
    );
  }
}



cart_provider.dart

class CartProvider with ChangeNotifier {
  Map<String, CartModel> _cartItems = {};

  Map<String, CartModel> get cartItems {
    return {..._cartItems};
  }

  int get itemCount {
    return _cartItems.length;
  }

  void reduceItem(
    String productId,
    String productName,
    int quantity,
    double price,
  ) {
    if (quantity == 1) {
      _cartItems.remove(productId);
      notifyListeners();
    } else {
      _cartItems.update(
        productId,
        (cartItem) => CartModel(
          productId,
          cartItem.price,
          productName,
          cartItem.quantity - 1,
        ),
      );

      notifyListeners();
    }
  }

  void addItem(String productId, String productName, double price) {
    if (_cartItems.containsKey(productId)) {
      //add quantity
      _cartItems.update(productId, (existingCartItem) {
        return CartModel(
          existingCartItem.id,
          existingCartItem.price,
          existingCartItem.productName,
          existingCartItem.quantity + 1,
        );
      });
    }
    notifyListeners();
  }

  void addToCart(
      String productId, String productName, int quantity, double price) {
    _cartItems.putIfAbsent(
      productId,
      () {
        DBHelper.insert('cart_food', {
          'id': productId,
          'productName': productName,
          'quantity': quantity,
          'price': price,
        });
        return CartModel(
          productId,
          price,
          productName,
          1,
        );
      },
    );

    notifyListeners();
  }

  double get totalAmount {
    var total = 0.0;
    _cartItems.forEach((key, cartItem) {
      total += cartItem.price * cartItem.quantity;
    });

    return total;
  }

  void removeItem(String productId) async {
    _cartItems.remove(productId);

    notifyListeners();
    await DBHelper.delete(productId);
  }

  Future<void> fetchCartProducts() async {
        List<Map<String, CartModel>> dataList = await DBHelper.getData('cart_food');
    print(dataList);

    //_cartItems = dataList.map((e) => )

    _cartItems = dataList as Map<String, CartModel>;

  }
}

getData


static Future<List<Map<String, CartModel>>> getData(String table) async {
    final db = await DBHelper.database();
    return db.query(table);
  }


What did I wrong? I don't get it. please help

Upvotes: 0

Views: 466

Answers (1)

B.Eshaan
B.Eshaan

Reputation: 53

Is the data successfully uploaded to the database?

If so, here's what could be going wrong -- You're fetching the products in initState() as follows:

Provider.of<CartProvider>(context, listen: false).fetchCartProducts();

The problem here is "context". Generally, for a widget the perfect place to initialize and listen for data from the web is the initState() method. However "context" doesn't work in initState() because "context" comes into play after initState() is called. So, you can't invoke your provider class there. Try to use didChangeDependencies instead as follows:

var _isInit=true;

    @override
      void didChangeDependencies() {
      if(_isInit){
         _foodItems = ApiService.getFoodItems();
         Provider.of<CartProvider>(context,listen:false).fetchCartProducts();
         _isInit=false;
      }
        super.didChangeDependencies();
    }

Lmk if this works.

Upvotes: 1

Related Questions