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 the Products
class.
CodePudding user response:
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:
ChangeNotifierProxyProvider<Auth, Products>(
create: null,
update: (context, auth, previousProducts) => Products(auth.token,
previousProducts == null ? [] : 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 :)
CodePudding user response:
Do not use ChangeNotifierProxyProvider
to create a new object. This is a provider which depends on other objects as well to update it's value. Use just the Provider
by following way:
Provider(
create: (_) => MyModel(),
child: ...
)
This should be enough for your use case.