I'm new to coding in general and I am working in flutter right now. I've successfully been able to add single string objects into a list but I'm having issues adding an object with multiple strings into a list. I'd love some guidance if anyone's able to help!
This is my model
import 'dart:convert';
import 'package:json_annotation/json_annotation.dart';
@JsonSerializable(anyMap: true, explicitToJson: true)
class Product {
String productName;
String productDescription;
Product(this.productName, this.productDescription);
factory Product.fromJson(Map<String, dynamic> json) =>
_$ProductFromJson(json);
Map<String, dynamic> toJson() => _$ProductToJson(this);
}
Product _$ProductFromJson(Map<String, dynamic> json) {
return Product(
json['product name'] as String,
json['product description'] as String,
);
}
Map<String, dynamic> _$ProductToJson(Product instance) => <String, dynamic>{
'product name': instance.productName,
'product description': instance.productDescription,
};
//trying to add Product strings into products
class UserData {
...
final List<dynamic> accommodations; //successfully able to add single strings to list
final List<dynamic> products; //unable to add multiple string objects to this list
...
UserData(
{...
this.accommodations,
this.products
...}
);
Map<String, dynamic> toJson() => {"products": this.products};
}
Here is the database function to connect it to firestore
Future addProduct(List products) async {
Map<String, dynamic> productMap = {
'products': products.map((product) => products.toList())
};
await userCollection.doc(uid).update(productMap);
}
The await, which I've edited multiple times, either throws an error "ArgumentError (Invalid argument: Instance of 'Product')" OR "_TypeError (type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, Object>')"
Finally, here is the onPressed event which I'm trying to use to insert the two string values into the products list.
String _currentProductName;
String _currentProductDescription;
these are hooked up to textformfields
onChanged: (val) {
setState(() => _currentProductName = val);
},
onChanged: (val) {
setState(() => _currentProductDescription = val);
},
and the onPressed which I've also tried changing multiple times
RaisedButton(onPressed: () async {
userData.products.add(Product(
_currentProductName,
_currentProductDescription));
await DatabaseService(uid: user.uid).addProduct(userData.products);
}),
Thank you!
1 Answer 1
When naming JSON params, use Snail Case:
json['product_name'] as String, json['product_description'] as String,Avoid dynamic as a List Type when you have already declared a Custom type because it can lead to unexpected behaviors in apps.
Change
final List<Product> products;to
final List<dynamic> products;Now only
Producttype objects will be accepted into theproductslist.When converting list items into JSON, you need to convert each item to JSON and add them to a list. For this you can use
mapfunction.Change
Map<String, dynamic> toJson() => {"products": this.products};to
Map<String, dynamic> toJson() => {"products": products.map((e) => e.toJson()).toList()};Based on the code provided, I assume you want to add 1 Product (not multiple products at once) into the user object on the button press.
Future<void> addProduct(Product product) async { // Add the product to the user's product list products.add(product); // toJson() is the function to convert `User` object to a `Json Map` await userCollection.doc(uid).update(toJson()); }Then the complete
Userclass,class UserData { UserData({ required this.accommodations, required this.products, }); final List<dynamic> accommodations; //successfully able to add single strings to list final List<dynamic> products; //unable to add multiple string objects to this list Map<String, dynamic> toJson() => {"products": products.map((e) => e.toJson()).toList()}; Future<void> addProduct(Product product) async { products.add(product); await userCollection.doc(uid).update(toJson()); } }
addProductandButonPress? They both do similar operations. \$\endgroup\$