setter error in flutter while assigning value to class variable In flutter - flutter

I have created a demo where I am storing data in divide using sqfliteHelper and I want to create a object list to store data in memory for temporary use but I am getting error while assigning value to class variable, regarding setter required
here is my code
class SqfliteProvider {
List<CategoryModel> _categorylist = [];
List<CategoryModel> get categories {
return _categorylist;
}
static Future<List<CategoryModel>?> fetchcategory() async {
final db = await _getdb();
List<CategoryModel> templist = [];
List<Map<String, dynamic>> maplist = await db.query('categorytb');
if (maplist.isEmpty) return null;
templist = maplist.map((e) => CategoryModel.frommap(e)).toList();
//this statement showing an error ...required setter..
_categorylist = templist;
return templist;
}
}

Related

for-loop should wait for future

I have a list of userIDs and I want to get a value from the database for each user and write it to a new list. But the for loop doesn't wait for the future and throws the error "Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 0"
List userIDs = ["gsdgsgsgda32", "gwerszhgda7h", "fsdgz675ehds"];
Future <dynamic> getList() async {
List items=[];
for (var i = 0; i < userIDs.length; i++) {
items[i] = await getUserItems(userIDs[i]);
}
return items;
}
Future <String?> getUserItems(String? _userID) async {
String? userItem=" ";
final FirebaseApp testApp = Firebase.app();
final FirebaseDatabase database = FirebaseDatabase.instanceFor(app: testApp);
database.ref().child('users').child(_userID!).once().then((pdata) {
userItem = pdata.snapshot.child('item').value as String?;
});
return userItem;
}
This is not problem with future. List items is empty so when you call items[0] = 3; there is no items[0] and you get RangeError. Proper way to add element to list is call items.add(3)
So your code should look like this:
List userIDs = ["gsdgsgsgda32", "gwerszhgda7h", "fsdgz675ehds"];
Future <dynamic> getList() async {
List items=[];
for (var i = 0; i < userIDs.length; i++) {
final item = await getUserItems(userIDs[i]);
items.add(item);
}
return items;
}
Future <String?> getUserItems(String? _userID) async {
String? userItem=" ";
final FirebaseApp testApp = Firebase.app();
final FirebaseDatabase database = FirebaseDatabase.instanceFor(app: testApp);
database.ref().child('users').child(_userID!).once().then((pdata) {
userItem = pdata.snapshot.child('item').value as String?;
});
return userItem;
}
By using .then you are telling dart to continue running and come back when the Future completes.
Instead you should use await inside getUserItems.
You have to fiddle around a bit but here's a suggestion to start with:
Future <String?> getUserItems(String? _userID) async {
String? userItem=" ";
final FirebaseApp testApp = Firebase.app();
final FirebaseDatabase database = FirebaseDatabase.instanceFor(app: testApp);
userItem = (await database.ref().child('users').child(_userID!).once()).snapshot.child('item').value as String?
return userItem;
}
Also using String? for userItem and setting it to " " is a bit of an anti pattern. Since you allow it to be nullable i'd suggest having it as null writing your logic around that.
Try to use it like this
Future <dynamic> getList() async {
List items=[];
userIDs.forEach((item) async {
items.add(await getUserItems(item));
});
return items;
}

riverpod repository list length doesnt change

class PopularProductViewModel extends ChangeNotifier {
final PopularProductRepo popularProductRepo;
PopularProductViewModel({required this.popularProductRepo});
List _popularProductList = [];
List get popularProductList => _popularProductList;
getPopularProductList() async {
var response = await popularProductRepo.getPopularProductList();
_popularProductList = [];
_popularProductList.addAll(Product.fromJson(response).products);
notifyListeners();
debugPrint("geldi model view");
debugPrint(_popularProductList.toString());
}
}
my list is coming from api but list length not update i tried all providers what is the true approach for repo pattern and refresh list length when datas coming?

_CastError (Null check operator used on a null value) from SQFLITE Flutter

I am trying to call this fetchall() method from totalprice() method, but every time it throws this error.
Here is my fetchall() method -
Future<List<CartModel>>? fetchall() async {
List<Map<String, Object?>>? map = await database?.query(tablename);
List<CartModel> cartproducts = [];
CartModel singleproduct = CartModel();
for (Map<String, Object?> i in map!) {
cartproducts.add(CartModel.fromJson(i));
singleproduct = CartModel.fromJson(i);
a = a + singleproduct.price!.toInt();
}
return cartproducts;
and this is the totalprice() method -
Future<int> totalprice() async {
int totalprice = 0;
List<CartModel>? products = await fetchall();
if (products != null) {
for (var i in products) {
totalprice = (totalprice + i.price!.toInt() * i.quantity!.toInt());
}
}
return totalprice;
Thanks for any little help.
Your line
List<Map<String, Object?>>? map = await database?.query(tablename);
Is probably assigning a null value to your map variable which your are later using with a null check operator ! which means that you are sure that it's not null, but the type List<Map<String, Object?>>? in the mentioned line gives it the ability to be null.
You can solve this by adding a null check before using the map variable like so
Future<List<CartModel>>? fetchall() async {
List<Map<String, Object?>>? map = await database?.query(tablename);
List<CartModel> cartproducts = [];
CartModel singleproduct = CartModel();
if(map != null)
for (Map<String, Object?> i in map!) {
cartproducts.add(CartModel.fromJson(i));
singleproduct = CartModel.fromJson(i);
a = a + singleproduct.price!.toInt();
}
}
return cartproducts;
}
Additional advice
For better code quality and readability, please follow variable naming conventions. For dart, make sure are your variables and methods are camelCase
so instead of fetchall => fetchAll
instead of cartproducts => cartProducts
instead of singleproduct => singleProduct
And so on...

Flutter - await/async on a List - why does this only work when not using declarations?

Still new to Flutter :(. Can anyone help...
I have a class that stores a bunch of project information. One part of this is a list of topics (for push notification), which it grabs from a JSON file.
I apply a getter for the list of topics, and when getting it it calls an async function which will return a List
Future<List<String>> _pntopics() async{
final _json = await http.get(Uri.parse(_topicsUrl));
if (_json.statusCode == 200) {
return (jsonDecode(_json.body));
}else {
return [""];
}
}
Future<List<String>> get topics => _pntopics();
In my main.dart file, it calls this value like so...
Future<List<String>> _topiclist = await projectvalues.topics;
The response is however empty, pressumably because it is a Future - so it is grabbing the empty value before it is filled.
But I can't remove the "Future" part from the async method, because asnc methods require a Future definition.
Then I decided to remove the declarations entirely:
_pntopics() async{
final _json = await http.get(Uri.parse(_topicsUrl));
if (_json.statusCode == 200) {
return (jsonDecode(_json.body));
}else {
return [""];
}
}
get topics => _pntopics();
and in main.dart, a general declaration...
var _topiclist = await projectvalues.topics;
...and this works!
So what declaration should I actually be using for this to work? I'm happy to not use declarations but we're always to declare everthing.
You should return back Future<List<String>> return types to the function and the getter but for _topicslist you must use var, final or List<String> declaration because:
(await Future<T>) == T
i.e.
var _topiclist = await projectvalues.topics; // The type of _topiclist is List<String>
final _topiclist = await projectvalues.topics; // The type of _topiclist is List<String>
UPDATE
Your code should be:
Future<List<String>> _pntopics() async{
final _json = await http.get(Uri.parse(_topicsUrl));
if (_json.statusCode == 200) {
return List<String>.from(jsonDecode(_json.body));
}else {
return <String>[""];
}
}
Doing this you force _pnptopics returns List<String> as jsonDecode returns List<dynamic>.
P.S. It is good practice do not use dynamic types where they can be changed to specified types.

Type 'List<dynamic>' is not a subtype of type 'List<SubCategoryData>'

I am trying to assigning the list to list of object, but it is showing the above exception.
List<SubCategoryData>categoryNames = new List<SubCategoryData>();
List<String>categorieslist = [];
bool isFirst=true;
Future<SubCategoryModel>fetchCategories(BuildContext context) async {
String url = "http://106.51.64.251:380/onnet_api/subcatListByCategory.php";
var body = new Map<String,String>();
body['publisherid']= 102.toString();
body['tag'] = "category";
body['subtag']= "list";
body['parentId'] = 10.toString();
http.Response res = await http.post(url,body: body);
final categoryjsondata = json.decode(res.body);
var map = Map<String,dynamic>.from(categoryjsondata);
var categoryResponse = SubCategoryModel.fromJson(map);
if(res.statusCode == 200){
print('category Response: $categoryResponse');
if(categoryResponse.status == 1){
//final categoryModel = json.decode(res.body);
categoryNames = categoryjsondata['data']as List;
print('category data: $categoryNames');
/* for(var model in categorieslist){
categoryNames.add(new SubCategoryData.fromJson(model));
}*/
/* SharedPreferences prefs = await SharedPreferences.getInstance();
print("cat List Size: $categories");
prefs.setStringList("categorylist", categories);*/
Navigator.push(context, MaterialPageRoute(builder: (context)=> ChewieDemo(imageData: images[0],
categoryData:categoryNames.toList())));
}
}
}
By seeing my code, for categoryNames I am trying to assigning the data to this then it is showing the exception.
Try to change your code to:
List<SubCategoryData> categoryNames = new ArrayList<>();
Hopefully this will solve your problem.
replace the following:
categoryNames = categoryjsondata['data']as List;
by
for(var model in categoryData){
categoryNames.add(new SubCategoryData.fromJson(model));
}
because the first returns a List the second returns a List
Your problem resides here:
categoryNames = categoryjsondata['data']as List;
categoryNames is already defined and initialized and its type is List<SubCategoryData>. In the line above you are trying to assign a List<dynamic> to it. That's a different type and that's the cause of the error. If you assign that to some other variable you can use it freely:
final categoryNamesList = categoryjsondata['data'] as List;
BTW then you don't have to call .toList() in the next lines, because this variable is already a list.
If explicity not defined the lists are of type dynamic, So explicitly state the value of the model. i.e
Convert
categoryNames = categoryjsondata['data']as List;
to
categoryNames = List<SubCategoryData>.from(categoryjsondata['data']);