A value of type 'Rx<Future<List<SectionsDBStat>>*>*' can't be assigned to a variable of type - flutter

I am learning Flutter and GetX.
I have got Model:
class SectionsDBStat {
int notificationsTotalCount;
int notificationsWaitingForProcessing;
DateTime notificationsLastArchiveDate;
SectionsDBStat({
required this.notificationsTotalCount,
required this.notificationsWaitingForProcessing,
required this.notificationsLastArchiveDate
});
factory SectionsDBStat.fromJson(Map<String, dynamic> json) {
return SectionsDBStat(
notificationsTotalCount: json['notificationsTotalCount'],
notificationsWaitingForProcessing: json['notificationsWaitingForProcessing'],
notificationsLastArchiveDate: DateTime.parse(json['notificationsLastArchiveDate'])
);
}
}
I am trying to create Getx contoller that receive data from http:
class SectionsStatController extends GetxController {
SectionsDBStat sectionsDBStat = Future.value(<SectionsDBStat>).obs;
getStat() async {
var value = await http.get('${url}/stat?total');
if(value.statusCode == 200) {
Map<String, dynamic> valueMap = jsonDecode(value.body)['data'];
sectionsDBStat = SectionsDBStat.fromJson(valueMap);
update();
} else {
print("Can't get stat: ${value.statusCode}");
}
}
}
I am getting an error:
A value of type 'Rx<Future<List<SectionsDBStat>>*>*' can't be assigned to a variable of type 'SectionsDBStat'.
So I should use another type. But what? I tried final but got error:
'sectionsDBStat' can't be used as a setter because it's final.

I don't know why are you using Future, here you are trying to assign Rx<Future<List<SectionsDBStat>>*> to sectionsDBStat and that is not possible
Replace this line
SectionsDBStat sectionsDBStat = Future.value(<SectionsDBStat>).obs;
with this
final sectionsDBStat = SectionsDBStat().obs;
and then assign it like this
sectionsDBStat.value = SectionsDBStat.fromJson(valueMap);

Related

Why I am getting Instance members can't be accessed from a factory constructor?

I am getting following errors:
Instance members can't be accessed from a factory constructor. (Documentation) Try removing the reference to the instance member.
The argument type 'List<Map<String, dynamic>>?' can't be assigned to the parameter type 'List<Vaccination>'. (Documentation)
at line _convertVaccinations(json['vaccinations'] as List<dynamic>));
Code:
final String name;
final String? notes;
final String type;
final List<Vaccination> vaccination;
final String? referenceId;
Pet(this.name, {this.notes, required this.type, required this.vaccination, this.referenceId});
factory Pet.fromJson(Map<String, dynamic> json) =>
Pet(
json['name'] as String,
notes: json['notes'] as String,
type: json['types'] as String,
referenceId: json['referenceId'] as String,
vaccination:
_convertVaccinations(json['vaccinations'] as List<dynamic>));
List<Map<String, dynamic>>? _convertVaccinations(List<dynamic>? vaccinations) {
if (vaccinations == null) {
return null;
} else {
final vaccinationMap = <Map<String, dynamic>>[];
for (var element in vaccinations) {
vaccinationMap.add(element.toJson);
}
return vaccinationMap;
}
}
Factory and instance member error:
Well it is because factory Pet.fromJson(...) is a factory constructor, and the class method _convertVaccinations(...) is an instance member.
If you make _convertVaccinations(...) static, it will accept the use of it in the factory constructor.
Argument error:
vaccination is of type List<Vaccination> and the method _convertVaccination(...) returns either null or List<Map<String, dynamic>>
In other words, you cannot assign null to List<T> unless it says List<T>? and the class Vaccination is not a Map<String, dynamic>
Maybe you want to do something like final List<Vaccination>? vaccinations; OR return <Vaccination>[] instead of null if vaccinations == null.
So you'd probably want to do write _convertVaccinations(...) as:
static List<Vaccination>? _convertVaccination(List<dynamic>? vaccinations) {
return vaccinations?.map((e) => Vaccination.fromJson(e as Map<String,dynamic>).toList();
}
or:
static List<Vaccination> _convertVaccination(List<dynamic>? vaccinations) {
return vaccinations?.map((e) => Vaccination.fromJson(e as Map<String,dynamic>).toList() ?? <Vaccination>[];
}
Side note: Maybe you have more methods that you haven't presented here. Because it looks a bit wonky when your Pet.fromJson(...) use a element.toJson down the call stack.

The argument type 'ProductModel?' can't be assigned to the parameter type 'ProductModel'

I'm making a midel to upload product image,price and name to firebase then i face this error (The argument type 'ProductModel?' can't be assigned to the parameter type 'ProductModel'.)
class ProductProvider with ChangeNotifier {
List<ProductModel> pizzaProductList = [];
ProductModel? productModel;
fatchPizzaproductData() async {
// List<ProductModel> newList = [];
QuerySnapshot value =
await FirebaseFirestore.instance.collection("PizzaProducts").get();
pizzaProductList = value.docs.map((element) {
return ProductModel(
productImage: element.get("productImage"),
productName: element.get("productName"),
productPrice: element.get("productPrice"),
);
}).toList();
}
get getPizzaproductDataList {
return pizzaProductList;
}
}
The problem is that productModel is a nullable type, whereas pizzaProduct is a List of non-nullable ProductModels.
Instead of storing a property productModel on your class, consider mapping directly from value.docs to pizzaProduct, and removing the intermediate step of storing the model in productModel:
class ProductProvider with ChangeNotifier {
List<ProductModel> pizzaProduct = [];
Future<void> fetchPizzaProductData() async {
QuerySnapshot value =
await FirebaseFirestore.instance.collection("PizzaProducts").get();
pizzaProduct = value.docs.map((element) {
return ProductModel(
productImage: element.get("productImage"),
productName: element.get("productName"),
productPrice: element.get("productPrice"),
);
}).toList();
// Since this is a ChangeNotifier, I'm assuming you might want to
// notify listeners when `pizzaProduct` changes. Disregard this line
// if that's not the case.
notifyListeners();
}
}

Having trouble creating generic Dart constructor for Json conversion

To all Dart gurus: I'm trying to implement a generic networking layer in Dart that converts REST service response to a specified model class:
// The idea is to make a network call and get a deserialized model as a response:
final token =
await _authNetworkService.execute<AccessTokenResponse>(request);
Here is the implementation:
// Model interface
abstract class JsonConvertible {
Map<String, dynamic> toJson();
JsonConvertible.fromJson(Map<String, dynamic> json);
}
// Model
class AccessTokenResponse extends JsonConvertible {
String? accessToken;
#override
Map<String, dynamic> toJson() {
return {};
}
#override
AccessTokenResponse.fromJson(Map<String, dynamic> json)
: super.fromJson(json) {
accessToken = json['access_token'];
}
}
// Network response class
class NetworkResponse<Model> {
Model data;
NetworkResponse.ok(this.data);
}
// Class to create a valid network service request
class NetworkRequest {
}
// Class that performs all network calls
class NetworkService {
Future<NetworkResponse<M>> execute<M extends JsonConvertible>(NetworkRequest request) async {
// For simplicity replaced all DIO calls with static data:
final response = {'data': {'access_token': 'XXX'}};
return NetworkResponse.ok(M.fromJson(response['data'])); //<- Fails here with error: Method 'fromJson' isn't defined for the type 'Type'...
}
}
DartPad: https://dartpad.dev/?id=9a29a7e49a084e69fd1d8078d5f2b977
How can I achieve expected behavior?
one way you can solve this is by passing the fromJson constructor as an argument to the execute function but this will add another step for every time execute is called
// Class that performs all network calls
class NetworkService {
Future<NetworkResponse<M>> execute<M extends JsonConvertible>(NetworkRequest request,M Function(Map<String, dynamic>) parser ) async {
// For simplicity replaced all DIO calls with static data:
final response = {'data': {'access_token': 'XXX'}};
return NetworkResponse.ok( parser(response['data']!)); //<- Fails here with error: Method 'fromJson' isn't defined for the type 'Type'...
}
}
and this is how you would call the execute function
final token =
await _authNetworkService.execute<AccessTokenResponse>(request,AccessTokenResponse.fromJson);

The argument type 'Object?' can't be assigned to the parameter type 'Map<dynamic, dynamic>'. GetX

so basically i'm frustrated by this 'Object?' type, i already tried t change its type in core file but i was worried to cause a weird behavior in the future. heres my code any kind of help will be appreciated
class HomeViewModel extends GetxController{
List<CategoryModel> get categorymodel => _categorymodel;
late DocumentSnapshot doc;
List<CategoryModel> _categorymodel = [];
final CollectionReference _categoryCollectionRef =
FirebaseFirestore.instance.collection('categories');
HomeViewModel(){
getCategory();
}
getCategory()async{
_categoryCollectionRef.get().then((value) {
for(int i = 0; i<value.docs.length;i++){
_categorymodel.add(CategoryModel.fromJson(value.docs[i].data()));
}
});
}
}
and this one is from my model class:
class CategoryModel {
late String name, image;
CategoryModel({required this.name, required this.image});
CategoryModel.fromJson(Map<dynamic, dynamic> map) {
if (map == null) {
return;
}
name = map['name'];
image = map['image'];
}
toJson() {
return {
'name': name,
'image': image,
};
}
}
You need to specify the type of data you're expecting from the DocumentSnapshot.
Change this line:
_categorymodel.add(CategoryModel.fromJson(value.docs[i].data()));
to this:
_categorymodel.add(CategoryModel.fromJson(value.docs[i].data() as Map<String, dynamic>));
Check out the guide for migration to cloud_firestore 2.0.0.

Flutter 2.0 The return type of getter 'xxxx' is 'dynamic' which isn't a subtype of the type 'List<dynamic>' of its setter 'xxxx'

I'm recently migrate my code to flutter 2.0, but I'm getting this error:
error: The return type of getter 'tabbarcatinfo' is 'dynamic' which isn't a subtype of the type 'List' of its setter 'tabbarcatinfo'.
import 'package:flutter/material.dart';
List _tabbarcatinfo = [];
class TabBarCategoriesInfo with ChangeNotifier{
static late List<String> name;
get tabbarcatinfo {
return _tabbarcatinfo;
}
set tabbarcatinfo(List Listita) {
_tabbarcatinfo = Listita;
notifyListeners();
}
void addData(List Listita) {
_tabbarcatinfo.add(Listita);
//notifyListeners();
}
}
You have not properly defined types in your code.
Use it like this.
List<String> _tabbarcatinfo = [];
class TabBarCategoriesInfo with ChangeNotifier {
static late List<String> name;
List<String> get tabbarcatinfo {
return _tabbarcatinfo;
}
set tabbarcatinfo(List<String> Listita) {
_tabbarcatinfo = Listita;
notifyListeners();
}
void addData(String item) {
_tabbarcatinfo.add(item);
//notifyListeners();
}
}
Comment if you have any particular doubt about a line and I will elaborate by answer to explain it.
Try this
get tabbarcatinfo {
return [..._tabbarcatinfo] as List<dynamic>;
}
Edit: Add the cast List<dynamic> in return statement.
Need set a type before get.
List get tabbarcatinfo
And anothrw question, your list doesn't have a type? If I'm not mistaken it must have any type.