The argument type 'Products Function(BuildContext, dynamic, dynamic)' can't be assigned to the parameter type 'Products Function(BuildContext)'
I am assuming you are following Maximillian's udemy course. You are using ChangeNotifierProxy because your Products provider is dependent on Auth provider's variables.
ChangeNotifierProxyProvider<MyModel, MyChangeNotifier>(
create: (_) => MyChangeNotifier(),
update: (_, myModel, myNotifier) => myNotifier
..update(myModel),
child: ...
);
This is how to define a ChangeNotifierProxyProvider. In your case, it will be:
without null safety migration
ChangeNotifierProxyProvider<Auth, Products>(
create: null,
update: (context, auth, previousProducts) => Products(auth.token,
previousProducts == null ? [] : previousProducts.items,
auth.userId)),
with null safety migration
ChangeNotifierProxyProvider<Auth, Products>(
create: (ctx) => Products('', '', []),
update: (context, auth, previousProducts) =>
Products(auth.token,previousProducts.items,auth.userId)),
Still if you see any error related to update then you need to upgrade your packages.
Let me know if you further need help :)
ensan3kamel
Updated on January 01, 2023Comments
-
ensan3kamel over 1 year
I am a new learner following a Flutter tutorial that is written in previous version and I get the following errors with this code:
main.ts:
void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider.value( value: Auth(), ), ChangeNotifierProxyProvider<Auth, Products>( create: (ctx, auth, previousProducts) => Products( auth.token, auth.userId, previousProducts == null ? [] : previousProducts.items, ), ), ChangeNotifierProvider.value( value: Cart(), ), ChangeNotifierProxyProvider<Auth, Orders>( create: (ctx, auth, previousOrders) => Orders( auth.token, auth.userId, previousOrders == null ? [] : previousOrders.orders, ), ), ], child: Consumer<Auth>( builder: (ctx, auth, _) => MaterialApp( title: 'MyShop', theme: ThemeData( primarySwatch: Colors.purple, textSelectionTheme: TextSelectionThemeData( selectionColor: Colors.deepOrange, selectionHandleColor: Colors.blue, ), fontFamily: 'Lato', pageTransitionsTheme: PageTransitionsTheme( builders: { TargetPlatform.android: CustomPageTransitionBuilder(), TargetPlatform.iOS: CustomPageTransitionBuilder(), }, ), ), home: auth.isAuth ? ProductsOverviewScreen() : FutureBuilder( future: auth.tryAutoLogin(), builder: (ctx, authResultSnapshot) => authResultSnapshot.connectionState == ConnectionState.waiting ? SplashScreen() : AuthScreen(), ), routes: { ProductDetailScreen.routeName: (ctx) => ProductDetailScreen(), CartScreen.routeName: (ctx) => CartScreen(), OrdersScreen.routeName: (ctx) => OrdersScreen(), UserProductsScreen.routeName: (ctx) => UserProductsScreen(), EditProductScreen.routeName: (ctx) => EditProductScreen(), }, ), ), ); } }
The named parameter 'update' is required, but there's no corresponding argument. Try adding the required argument.
The argument type 'Products Function(BuildContext, dynamic, dynamic)' can't be assigned to the parameter type 'Products Function(BuildContext)'.
All the errors come from this part of the code( and the other similar part):
ChangeNotifierProxyProvider<Auth, Products>( create: (ctx, auth, previousProducts) => Products( auth.token, auth.userId, previousProducts == null ? [] : previousProducts.items, ),
And this is the Products.ts:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import '../models/http_exception.dart'; import './product.dart'; class Products with ChangeNotifier { List<Product> _items = []; final String authToken; final String userId; Products(this.authToken, this.userId, this._items); List<Product> get items { // if (_showFavoritesOnly) { // return _items.where((prodItem) => prodItem.isFavorite).toList(); // } return [..._items]; } List<Product> get favoriteItems { return _items.where((prodItem) => prodItem.isFavorite).toList(); } Product findById(String id) { return _items.firstWhere((prod) => prod.id == id); } Future<void> fetchAndSetProducts([bool filterByUser = false]) async { final filterString = filterByUser ? 'orderBy="creatorId"&equalTo="$userId"' : ''; var url = Uri.parse( 'https://flutter-update.firebaseio.com/products.json?auth=$authToken&$filterString'); try { final response = await http.get(url); final extractedData = json.decode(response.body) as Map<String, dynamic>; if (extractedData == null) { return; } url = Uri.parse( 'https://flutter-update.firebaseio.com/userFavorites/$userId.json?auth=$authToken'); final favoriteResponse = await http.get(url); final favoriteData = json.decode(favoriteResponse.body); final List<Product> loadedProducts = []; extractedData.forEach((prodId, prodData) { loadedProducts.add(Product( id: prodId, title: prodData['title'], description: prodData['description'], price: prodData['price'], isFavorite: favoriteData == null ? false : favoriteData[prodId] ?? false, imageUrl: prodData['imageUrl'], )); }); _items = loadedProducts; notifyListeners(); } catch (error) { throw (error); } } Future<void> addProduct(Product product) async { final url = Uri.parse( 'https://flutter-update.firebaseio.com/products.json?auth=$authToken'); try { final response = await http.post( url, body: json.encode({ 'title': product.title, 'description': product.description, 'imageUrl': product.imageUrl, 'price': product.price, 'creatorId': userId, }), ); final newProduct = Product( title: product.title, description: product.description, price: product.price, imageUrl: product.imageUrl, id: json.decode(response.body)['name'], ); _items.add(newProduct); // _items.insert(0, newProduct); // at the start of the list notifyListeners(); } catch (error) { print(error); throw error; } } Future<void> updateProduct(String id, Product newProduct) async { final prodIndex = _items.indexWhere((prod) => prod.id == id); if (prodIndex >= 0) { final url = Uri.parse( 'https://flutter-update.firebaseio.com/products/$id.json?auth=$authToken'); await http.patch(url, body: json.encode({ 'title': newProduct.title, 'description': newProduct.description, 'imageUrl': newProduct.imageUrl, 'price': newProduct.price })); _items[prodIndex] = newProduct; notifyListeners(); } else { print('...'); } } Future<void> deleteProduct(String id) async { final url = Uri.parse( 'https://flutter-update.firebaseio.com/products/$id.json?auth=$authToken'); final existingProductIndex = _items.indexWhere((prod) => prod.id == id); Product? existingProduct = _items[existingProductIndex]; _items.removeAt(existingProductIndex); notifyListeners(); final response = await http.delete(url); if (response.statusCode >= 400) { _items.insert(existingProductIndex, existingProduct); notifyListeners(); throw HttpException('Could not delete product.'); } existingProduct = null; } }
I don't know what is the problem and how should I solve these errors? I can't find a required parameter named
update
in theProducts
class. -
ensan3kamel over 2 yearsThank you Sharib, Yes I am using that tutorial course and did what you suggested in code, but it didn't solve my problem and still I get this error message:
The argument type 'Null' can't be assigned to the parameter type 'Products Function(BuildContext)'.
For this line of codecreate: null,
-
ensan3kamel over 2 yearsI want to pass data of one provider to another provider . so I have used ChangeNotifierProxyProvider .
-
sharib ahmed over 2 yearsSorry for late reply. Please see the updated answer. @ensan3kamel
-
ensan3kamel over 2 yearsNo problem! I could solve the problem like I wrote as a new answer, but I am still interested to know if there is any difference between what I did and what you suggested. Is there any difference either between initializing the variables with empty variables(like what you suggested) or assigning
null
values to them( like what I did)? -
sharib ahmed over 2 yearsWhat you did is unnecessary because your project is by default null safety migrated and type cast is also not required. Please see my updated answer.