Instance member 'fromJson' can't be accessed using static access - flutter

I ran into a problem with my Flutter app. The error I get in news_service.dart is "The sample member 'fromJson' cannot be accessed using static access." error. Anyone know what this is about? I really don't understand... Thanks in advance!!
if (response.body.isNotEmpty) {
final responseJson = json.decode(response.body);
News news = News.fromJson(responseJson);
return news.articles;
}
return null;
}
}

Try to replace News.fromJson(responseJson); with News().fromJson(responseJson);

You should instantiate New class then call instance method fromJson this method is not static so can't be accessed directly.
final news = News();
//now call news.fromJson(responseJson)

The fromJson function needs to either be static, or a (factory) constructor. It is hard to give an exact working answer because you have not provided additional information that was asked from you, but the following sample fromJson implementation should work with little modification from your part:
News.fromJson(Map<String, dynamic> json)
: title = json['title'],
content = json['content'];
I am assuming your News data model has title and content fields, feel free to change it according to your exact data model.

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);

Flutter GetX RxList assign issue

Im trying to convert old code to new code syntax. I have a issue with RxList.
So I change postModel.assign(postDetail);
But In my news_detail page How I can access to value?
First of all you shouldn''t use postModel as a List as your API clearly returns a single post (NewsModel) by id and not a list of post (List of NewsModel). So using var postModel = <NewsModel>[].obs; is totally unnecessary in my opinion.
What you could do is:
final postModel = NewsModel().obs;
And then on API call:
postModel.value = postDetail;
And then on View:
Image.network(controller.postModel.value.imageUrl);
postModel is a List.
So you would need to access an item in that list, using an int index.
Something like this:
return Image.network(newsDetailController.postModel[0].imageUrl);

A way to read a String as dart code inside flutter?

I want to build a method to dynamically save attributes on a specific object
given the attribute name and the value to save I call the "save()" function to update the global targetObj
var targetObj = targetClass();
save(String attribute, String value){
targetObj.attribute = value;
print(targetObj.attribute);
}
But I'm getting the following error:
Class 'targetClass' has no instance setter 'attribute='.
Receiver: Instance of 'targetClass'
Tried calling: attribute="Foo"
The only thing that I can think of is that "attribute" due to being type String results in an error.
That lead me to think if there is a way to read a String as code, something like eval for php.
As #Randal mentioned, you cannot create class..method at runtime. Still, you can try something like this.
A certain class
class Foo {
dynamic bar1;
dynamic bar2;
// ...
}
Your save method
save(Foo fooObject, String attribute, dynamic value) {
if ("bar1" == attribute) fooObject.bar1 = value;
else if ("bar2" == attribute) fooObject.bar2 == value;
// ...
}
Dart (and thus flutter) does not have a way to compile and execute code at runtime (other than dart:mirrors, which is deprecated). You can build additional code that derives from other code using the various builder mechanisms, although it can be rather complicated to implement (and use!).

Deserialise JSON response from API into type in Dart

I'm going out of my mind trying to figure this out because it's such a simple thing to do and there's no information on it anywhere.
I have an API call that is returning a Student which is defined like this
class Student {
String photo;
String upn;
String fullName;
String studentClass;
String studentYear;
}
I'm using the dart http library to make a call to an API that returns an array of a number of students. All I want to do is deserialise the string returned by the API into a typed list so that I can actually do something with it.
studentFuture.then((res) {
log(res.body.toString());
List<dynamic> dynamicList = jsonDecode(res.body);
var student = dynamicList[0] as Student;
});
Trying to cast it to Student using as doesn't work, I just get this
Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Student' in type cast
All I want is to be able to do something like this like you can in C#
var obj = DeserialiseJson<Type>(jsonString);
No matter what I try I can't get the string to be deserialised into an object, how do I do this?
You can't do this in Dart/Flutter in the way that you want. This is because in order to accomplish this functionality in C#, Java, or any other strongly-typed language that supports this feature, the language uses reflection under the hood to map JSON fields to object fields.
Dart also has reflection functionality in the dart:mirror library. However, this library is disabled in Flutter due to its tendency to create large app footprints due to all the debug information for various types and fields and things needing to be included in the compiled binary. (That's the very simple explanation: the official reason given by the Flutter team goes into more detail.)
What this means is when you deserialize a JSON string, you get an object that is essentially a List<dynamic> or Map<String, dynamic> (depending on the JSON string in question; it may even just be some primitive value). Assuming the latter, you cannot directly convert between a Map and a Student because they are completely different types with nothing in common. There is no implicit way to take the Map and generate a Student because the reflection tools necessary to do so don't exist within a Flutter app. As a result, you get an error saying you cannot convert a Map to a Student, as you can see.
To work around this, you are encouraged to add a toJson/fromJson method to your model class so you can explicitly generate an instance of the class from a deserialized JSON string:
class Student {
String photo;
String upn;
String fullName;
String studentClass;
String studentYear;
factory Student.fromJson(Map<String, dynamic> jsonData) {
return Student()
..photo = jsonData['photo']
..upn = jsonData['upn']
..fullName = jsonData['fullName']
..studentClass = jsonData['studentClass']
..studentYear = jsonData['studentYear'];
}
}
And use it like so:
studentFuture.then((res) {
log(res.body.toString());
List<dynamic> dynamicList = jsonDecode(res.body);
var student = Student.fromJson(dynamicList[0]);
});
This is all well and good, but if you have more than a few model classes you will quickly realize that adding this boilerplate code to every model class gets really tedious really quick. That's why various packages exist to try and alleviate the burden with automatic code generation, such as json_serializable and freezed.
TL;DR: What you are asking for is not currently possible in Flutter Dart, and that isn't likely to change any time soon. You need to either write a manual factory constructor to make the conversion or use a code-gen package that generates the constructors for you.
Have a look at https://pub.dev/packages/json_serializable which, through code generation, will give you methods like
#JsonSerializable()
class Student {
String photo;
String upn;
String fullName;
String studentClass;
String studentYear;
Student({this.photo, this.upn, this.fullName, this.studentClass, this.studentYear});
factory Student.fromJson(Map<String, dynamic> json) => _$StudentFromJson(json);
Map<String, dynamic> toJson() => _$StudentToJson(this);
}
Then you can do:
var list = jsonDecode(res.body);
for (var map in list) {
print(Student.fromJson(map)); // Student class
}

Please help me understand fromMap and toMap from this code?

I got this code from the internet and I can not seem to understand it or find anything on the internet for it.
In the code below toMap is a method that returns 2 items, How is that possible?
And what is fromMap, is it a user created method? I thought methods used {} or => so it is a bit confusing.
Also, what is the key here for the Map? Can the map only store 2 categories of items? One is the key and the other is the value. Or it can have one key but multiple categories of values.
For example, there might be a single unique key, which could help take out the task title, time, reminder data, notes, etc as values of the map.
class Task {
String title;
bool completed;
Task({
this.title,
this.completed = false,
});
Task.fromMap(Map<String, dynamic> map): title = map['title'],completed = map['completed'];
updateTitle(title) {
this.title = title;
}
Map toMap() {
return {
'title': title,
'completed': completed,
};
}
}
In the code below toMap is a method that returns 2 items, How is that
possible?
No, it returns a Map (with two items). More about maps can be found here.
And what is fromMap, is it a user created method? I thought methods
used {} or => so it is a bit confusing.
Task.fromMap(Map<String, dynamic> map) is called "named constructor". The : title = map['title'],completed = map['completed'] part is initializer list
My understanding is;
In fromMap, you retrieve the title and completed from some map, and save it in your local variables.
In the toMap you take the saved values in your local variables and can return a Map.
The key is whatever you put you chose it to be, but here you chose one key to be titleand one to be completed.
Does this help you?
First of all we discuss about FormMap So what is fromMap()?
whenever you have any api and at firetime you will get json format so when you want to convert that data into any class format then you have to do like
Map temp = json.decode(response.body);
so your function can understand map key and retrieve that value and set in class local variable
and now Second point is toMap So what is toMap()?
Whenever you want to post something into api or somewhere you have map data so you can post in api
like
Abc a = Abc(name:"hari",address:"india");
a.toMap();