I have a ProviderNotFoundException problem?

16 Views Asked by At

I'm applying the Provider pattern to manage the state of my application So I have a ListView of CartItem and when I dismiss the CartItem from it a ProviderNotFoundException occur the logic and the code seems fine to me and I don't know where the problem exactly belongs .

I tried to change the Dismissed widget with an IconButton near my CartItem widget and the same problem occur .

enter image description here

here you can find My code :

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/cart.dart';

class CartItem extends StatelessWidget {
  final String id;
  final String productId;
  final double price;
  final int quantity;
  final String title;
  CartItem(this.id, this.productId, this.price, this.quantity, this.title);

  @override
  Widget build(BuildContext context) {
    return Dismissible(
      key: ValueKey(id),
      background: Container(
        color: Theme.of(context).colorScheme.onSecondary,
        alignment: Alignment.centerRight,
        padding: const EdgeInsets.only(right: 20),
        margin: const EdgeInsets.symmetric(
          horizontal: 15,
          vertical: 4,
        ),
        child: const Icon(
          Icons.delete,
          color: Colors.white,
          size: 40,
        ),
      ),
      direction: DismissDirection.endToStart,
      onDismissed: (direction) {
        Provider.of<Cart>(context, listen: false).removeItem(productId);
      },
      child: Card(
        margin: const EdgeInsets.symmetric(
          horizontal: 15,
          vertical: 4,
        ),
        child: Padding(
          padding: const EdgeInsets.all(8),
          child: ListTile(
            leading: CircleAvatar(
              child: Padding(
                  padding: const EdgeInsets.all(5),
                  child: FittedBox(child: Text('\$${price}'))),
            ),
            title: Text(title),
            subtitle: Text('Total: \$${(price * quantity)}'),
            trailing: Text('$quantity x'),
          ),
        ),
      ),
    );
  }
}

import 'package:flutter/foundation.dart';

class CartItem {
  final String id;
  final String title;
  final int quantity;
  final double price;
  CartItem(
    this.id,
    this.title,
    this.price,
    this.quantity,
  );
}

class Cart with ChangeNotifier {
  Map<String, CartItem> _items = {};

  Map<String, CartItem> items() {
    return {..._items};
  }

  int get itemCount {
    return _items.length;
  }

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

  void addItem(String productId, double price, String title) {
    if (_items.containsKey(productId)) {
      //change the quantity ...
      _items.update(
        productId,
        (existingCartItem) => CartItem(
            existingCartItem.id,
            existingCartItem.title,
            existingCartItem.price,
            existingCartItem.quantity + 1),
      );
      notifyListeners();
    } else {
      _items.putIfAbsent(
          productId,
          () => CartItem(
                DateTime.now().toString(),
                title,
                price,
                1,
              ));
      notifyListeners();
    }
  }

  void removeItem(String productId) {
    _items.remove(productId);
    notifyListeners();
  }

  void clear() {
    _items = {};
    notifyListeners();
  }
}

import 'package:flutter/material.dart';

import 'package:provider/provider.dart';
import '../Providers/orders.dart';
import '../screens/cart_screen.dart';
import './screens/product_detail_screen.dart';
import './screens/products_overview_screen.dart';
import './Providers/products_provider.dart';
import './Providers/cart.dart';
import './screens/orders_screen.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    `//The ChangeNotifierProvider is a widget that makes us listen` `whenever that class updates only the child widget will rebuid`
    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(
          //if we use ChangeNotifierProvider() widget and need
          //create: (context) => Products(),

          //or use ChangeNotifierProvider.value() and the value 
           attribute we use this shortcut
          //because we don't need the context argument of the 
        function we were creating using ChangeNotifierProvider() widget
          value: Products(),
        ),
        ChangeNotifierProvider<Cart>(create: (_) => Cart()),
        /*ChangeNotifierProvider.value(
          value: Cart(),
        ),*/
        ChangeNotifierProvider.value(
          value: Orders(),
        ),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Shop app',
        theme: ThemeData(
          primarySwatch: Colors.purple,
          accentColor: Colors.deepOrange,
          colorScheme: const ColorScheme.light(
              primary: Colors.purpleAccent, onSecondary: Colors.deepOrange),
          fontFamily: 'Lato',
          textTheme: ThemeData.light().textTheme.copyWith(
                bodyLarge:
                    const TextStyle(color: Color.fromRGBO(25, 51, 51, 1)),
                bodySmall:
                    const TextStyle(color: Color.fromRGBO(25, 51, 51, 1)),
                titleLarge: const TextStyle(
                  fontSize: 20.0,
                  fontFamily: 'lato',
                  fontWeight: FontWeight.bold,
                ),
                titleMedium: const TextStyle(
                  fontFamily: 'Raleway',
                  fontWeight: FontWeight.bold,
                  color: Colors.white70,
                  fontSize: 21.0,
                ),
              ),
        ),
        home: ProductsOverviewScreen(),
        routes: {
          ProductDetailScreen.routeName: (ctx) => ProductDetailScreen(),
          CartScreen.routeName: (ctx) => CartScreen(),
          OrdersScreen.routeName: (ctx) => const OrdersScreen(),
        },
      ),
    );
  }
}
0

There are 0 best solutions below