Migrating from Provider to Riverpod - flutter

I am stuck using Provider and came across Riverpod which is just the next gen of Provider. I am trying to create a StreamProvider using Riverpod but I am getting an error.
Here is the code for creating the StreamProvider:
final trxnStreamProvider = StreamProvider.autoDispose<List<Trxns>>((ref) {
final stream = firestoreService.getAgencyTrxns();
return stream.map((snapshot) => snapshot.docs.map((doc) => Trxns.fromFirestore(doc.data)).toList());
});
The error I get marks the code "doc.data". Here is the error text:
The argument type 'Object? Function()' can't be assigned to the parameter type 'Map<String, dynamic>'.
Here is the code for "Trxns.fromFirestore(doc.data)":
Trxns.fromFirestore(Map<String, dynamic> firestore)
: clientFName = firestore['clientFName'],
clientLName = firestore['clientLName'];
I'm still new to this and am having a hard time understanding the error message. Is it saying that "doc.data" is not the right type? If so, how do I fix this? If not, what is wrong and how do I fix it?

Map<String, dynamic> data() => dartify(jsObject.data());
data is a method so you need to call it:
doc.data()
doc.data mean you want to pass a function

Related

In Flutter, an object's fromJson method generated by freezed occured type cast error, DateTime -> String

I have used freezed library to manage my Remote DTO classes and Ui Models.
In this question case, my Object LifeDiagnosisResult DTO and Ui Model only have one difference - createdAt field.
When I put data, I used SharedPreference (because backend is not yet built) and put my List value by jsonEncode function.
When I get a response from SharedPreference (because backend is not yet built) , I used jsonDecode to get Map Object.
To achieve my final wish, List Object, I added createdAt field like this.
void _handleListResponseSuccess(List<String> response) {
List<LifeDiagnosisResultUiModel>? uiModelList = response.map((e) {
Map<String, dynamic> map = jsonDecode(e) as Map<String, dynamic>;
map['createdAt'] = DateTime.now();
return LifeDiagnosisResultUiModel.fromJson(map);
}).toList();
if (uiModelList.isNotEmpty) {
setLifeDiagnosisResultUiModel(uiModelList[uiModelList.length - 1]);
}
_rxList(uiModelList);
}
But, when I ran this code, type casting error was caused.
The error message is this.
error type 'DateTime' is not a subtype of type 'String' in type cast
And this is my Ui Model's createdAt field.
I think Map's createdAt could not find correct field in Ui Model.
But I have no idea why...
Could you tell me what is wrong?
I found the answer...
it is not a real answer of my question, but it can explain why this issue happen.
In dart, Map's DateTime cannot be converted to Object's DateTime.
I dont know a detail process, but in type casting, Map's DateTime is converted to String type.
I don't know if I get it right, but if you want to test your fromJson method you could do it like this:
Map<String,dynamic> response={'att1':1234,'att2':'oneTwoThree','createdAt':DateTime(2022,08,22)};
return LifeDiagnosisResultUiModel.fromJson(response);

NoSuchMethodError: Class 'List<dynamic>' has no instance method 'cast' with matching arguments

I am trying to fetch Articles from my API servers,but i get NoSuchMethodError: Class 'List<dynamic>' has no instance method 'cast' with matching arguments error. Does anybody know how can i solve it?
List<Article> posts;
final response = await http.get(Uri.parse("$SERVER_IP/api/articles/?format=json"),
headers: <String, String>{"Authorization" : "Token ${globaltoken}"},);
final parsed = jsonDecode(utf8.decode(response.bodyBytes)).cast<String,dynamic>();
posts = parsed.map<Article>((json) => Article.fromJSON(json)).toList();
return posts;
You should not use cast() in the first place, because a nearby operation (in this case the parsed.map) already uses cast() for you and thus casts your desired type (Article). Omitting cast<String,dynamic>() should solve your error.
Please also refer to the dart documentation:
https://dart.dev/guides/language/effective-dart/usage#dont-use-cast-when-a-nearby-operation-will-do
https://dart.dev/guides/language/effective-dart/usage#avoid-using-cast

How to initialize Either Right to an empty value in flutter

I recently made the switch to null-safety in my flutter project, which brings a new kind of problem when using the Either type (from the dartz package)
For example, before I would have some properties in my class like this:
Either<Failure, List<Product>> _products;
I would then have a function to get the products, and consume it in my view.
However, now with null safety, I need to initialize this property, because it should never be null, instead I would like to have an empty list.
If I do this
Either<Failure, List<Product?>> _products = [];
I get this error
A value of type 'List<dynamic>' can't be assigned to a variable of type 'Either<Failure, List<Product?>>'.
So my question would be, how can I initialize this property to the right value of Either, with an empty list?
Have this go:
Either<Failure, List<Product?>> _products = right([]);
you can use the new 'late' keyword that fixes this issue
late Either<Failure, List<Product?>> _products;
read more about it here

Error while using Flutter with Riverpod and null safety

I am using Flutter with Riverpod and null safety for the first time and I have the following provider that should return ImageProfile or null.
final myProfileImageProvider = Provider.autoDispose.family<ProfileImage?, int>(
(ref, index) {
final images = ref.watch(editMyProfileViewModelProvider.state).images;
if (index < images.length) {
return images[index];
}
return null;
},
name: 'myProfileImageProvider',
);
I am reading the provider inside a function like this:
final profileImage = context.read<ProfileImage>(myProfileImageProvider(profileImageIndex));
But I am getting the following compiler error.
The argument type 'AutoDisposeProvider<ProfileImage?>' can't be assigned to the parameter
type 'ProviderBase<Object, ProfileImage?>' because 'ProfileImage?' is nullable and 'Object'
isn't.
Notice that inside a function, I can't use watch or useProvider. I must use context.read. Please note that useProvider() does solve the problem but can't use it inside a function. The problem is when reading the provider inside a function.
Any body out there know the answer to this?
I appreciate any help.
Thanks

Cannot access map object with []. operator [] is not defined

I am working on a mobile application using Flutter 1.7.8.
I collected data from the server in a form of a nested json object, e.g.
class Obj {
final String obj_to_access;
const Obj({this.obj_to_access});
factory Obj.fromJson(Map<String, dynamic> json) {
return Obj(
obj_to_access: json['item']
);
}
some_obj =
{
"id": some_id,
"nested_obj": Obj.fromJson(json["obj_to_access"])
}
However, I can't seem to access the nested Obj with '[]' and it always give me this error: The operator '[]' isn't defined for the class 'Obj'. Try defining the operator.
I saw that I should try defining the '[]' but I am not sure how. Please help thanks
The reason for the error is that you're passing a dynamic value to Obj.fromJson() instead of a Map - which it expects. To solve this issue, you can add cast as <Map<String, dynamic>> to the value to let the compiler know that it's a Map.