I am getting an Error: Could not find the correct Provider above this ProductItemScreen Widget whenever I press on a product Item even though I have set my provider as a parent of MaterialApp()
Below is the product_overview_screen.dart file which shows a gridview of the products on my screen
class ProductsOverviewScreen extends StatelessWidget {
static const routeName = '/prod_overview_Screen';
const ProductsOverviewScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final prodData = Provider.of<Products>(context); //Recieves data from provider file
return Scaffold(
appBar: AppBar(
title: const Text('My Shop'),
backgroundColor: Theme.of(context).primaryColor,
),
body: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 3 / 2,
),
itemCount: prodData.items.length,
itemBuilder: (ctx, i) => ProductItem(
imageUrl: prodData.items[i].imageUrl,
title: prodData.items[i].title,
id: prodData.items[i].id,
),
),
);
}
}
Below is also the Product_item.dart file where I pass the Id of the product to the next screen where I display the data of that particular product on the screen
class ProductItemScreen extends StatelessWidget {
static const routeName = '/prod_item_screen';
const ProductItemScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final prodIdPassed = ModalRoute.of(context)!.settings.arguments as String;
final prod = Provider.of<Products>(context).findById(prodIdPassed);
return Scaffold(
appBar: AppBar(
title: Text(prod.title),
backgroundColor: Theme.of(context).primaryColor,
),
body: Column(
children: [Image.asset(prod.imageUrl), Text(prod.title)],
),
);
}
}
Also below is the main.dart file where I have setup my provider for all available listeners
void main() {
runApp(
ChangeNotifierProvider(
create: (ctx) => Products(),
child: MaterialApp(
theme: ThemeData.light().copyWith(primaryColor: Colors.purple),
initialRoute: ProductsOverviewScreen.routeName,
routes: {
ProductsOverviewScreen.routeName: (ctx) =>
const ProductsOverviewScreen(),
ProductItemScreen.routeName: (ctx) => const ProductItemScreen(),
},
),
),
);
}
CodePudding user response:
Right below runApp, explicitly declare the class:
ChangeNotifierProvider<Products>(
CodePudding user response:
You did'nt provided providermodel class here Check this provider.
Mainmethod (not changed)
void main() {
var changeNotifierProvider = ChangeNotifierProvider(
create: (ctx) => Products(),
child: MaterialApp(
theme: ThemeData.light().copyWith(primaryColor: Colors.purple),
initialRoute: ProductsOverviewScreen.routeName,
routes: {
ProductsOverviewScreen.routeName: (ctx) =>
const ProductsOverviewScreen(),
ProductItemScreen.routeName: (ctx) => const ProductItemScreen(),
},
),
);
runApp(changeNotifierProvider);
}
Products provider (Added)
class Products extends ChangeNotifier {
Product? _findById;
List<Product> _items = [];
List<Product> get items => _items;
set items(List<Product> value) {
_items = value;
notifyListeners();
}
set items2(List<Product> value) {
_items = value;
// notifyListeners();
}
Product? get findById => _findById;
set findById(Product? value) {
_findById = _items.where((element) => element.id == value!.id).first;
notifyListeners();
}
set findById2(Product? value) {
_findById = _items.where((element) => element.id == value!.id).first;
// notifyListeners();
}
}
Sample Code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
var changeNotifierProvider = ChangeNotifierProvider(
create: (ctx) => Products(),
child: MaterialApp(
theme: ThemeData.light().copyWith(primaryColor: Colors.purple),
initialRoute: ProductsOverviewScreen.routeName,
routes: {
ProductsOverviewScreen.routeName: (ctx) =>
const ProductsOverviewScreen(),
ProductItemScreen.routeName: (ctx) => const ProductItemScreen(),
},
),
);
runApp(changeNotifierProvider);
}
class ProductItemScreen extends StatelessWidget {
static const routeName = '/prod_item_screen';
const ProductItemScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final prodIdPassed = ModalRoute.of(context)!.settings.arguments as String;
var product = new Product(imageUrl: "", title: "", id: prodIdPassed);
Provider.of<Products>(context).findById2 = product;
final prod = Provider.of<Products>(context).findById;
return Scaffold(
appBar: AppBar(
title: Text(prod!.title),
backgroundColor: Theme.of(context).primaryColor,
),
body: Column(
children: [Image.network(prod.imageUrl), Text(prod.title)],
),
);
}
}
class ProductsOverviewScreen extends StatelessWidget {
static const routeName = '/prod_overview_Screen';
const ProductsOverviewScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final prodData = Provider.of<Products>(context);
List<Product> item = [];
item.add(Product(
imageUrl:
"https://cdn.pixabay.com/photo/2013/07/13/14/08/apparel-162192_1280.png",
title: "lava",
id: "1"));
item.add(Product(
imageUrl:
"https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/classic-accessories-1516305397.jpg",
title: "hi",
id: "2"));
item.add(Product(
imageUrl: "https://images.indianexpress.com/2019/09/toys.jpg",
title: "hi",
id: "4"));
item.add(Product(
imageUrl: "https://m.media-amazon.com/images/I/51zEsraniRL._UX569_.jpg",
title: "hi",
id: "3"));
prodData.items2 = item; //Recieves data from provider file
return Scaffold(
appBar: AppBar(
title: const Text('My Shop'),
backgroundColor: Theme.of(context).primaryColor,
),
body: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 3 / 2,
),
itemCount: prodData.items.length,
itemBuilder: (ctx, i) => ProductItem(
imageUrl: prodData.items[i].imageUrl,
title: prodData.items[i].title,
id: prodData.items[i].id,
),
),
);
}
}
class ProductItem extends StatelessWidget {
var imageUrl;
var id;
var title;
ProductItem({Key? key, this.imageUrl, this.title, this.id}) : super(key: key);
@override
Widget build(BuildContext context) {
var column = Column(
children: [
Expanded(
child: Container(
// height: 125,
child: Image.network(
imageUrl,
alignment: Alignment.center,
fit: BoxFit.cover,
),
),
),
Center(
child: Text(
title " " id,
style: TextStyle(fontSize: 12),
))
],
);
return InkWell(
onTap: () {
Navigator.pushNamed(context, ProductItemScreen.routeName,
arguments: id);
},
child: column);
}
}
class Product {
var title;
var imageUrl;
var id;
Product({this.imageUrl, this.title, this.id});
}
class Products extends ChangeNotifier {
Product? _findById;
List<Product> _items = [];
List<Product> get items => _items;
set items(List<Product> value) {
_items = value;
notifyListeners();
}
set items2(List<Product> value) {
_items = value;
// notifyListeners();
}
Product? get findById => _findById;
set findById(Product? value) {
_findById = _items.where((element) => element.id == value!.id).first;
notifyListeners();
}
set findById2(Product? value) {
_findById = _items.where((element) => element.id == value!.id).first;
// notifyListeners();
}
}