The unnamed constructor is already defined - json

I created a Post Model class using Dart and got this error saying "message": "The unnamed constructor is already defined.\nTry giving one of the constructors a name". Thsi is how my code is below:
final String caption;
final String comments;
final String datePosted;
final int likes;
Post({
required this.caption,
required this.comments,
required this.datePosted,
required this.likes,
});
factory Post(Map<String, dynamic> json) {
return Post(
caption: json['Caption'],
comments: json['Comments'],
datePosted: json['Date Posted'],
likes: json['Likes'],
);
}
}
Please help I'd really appreciate it

change to this
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
caption: json['Caption'],
comments: json['Comments'],
datePosted: json['Date Posted'],
likes: json['Likes'],
);
}

Related

How to loop a list of maps from json api dart/flutter

I have create a class model to receive json data from API
class Competition {
int id;
String name;
String code;
String type;
String emblem;
Competition({
required this.id,
required this.name,
required this.code,
required this.type,
required this.emblem,
});
factory Competition.fromJson(Map<String, dynamic> data) {
return Competition(
id: data["matches"][0]["competition"]['id'],
name: data["matches"][0]["competition"]['name'],
code: data["matches"][0]["competition"]['code'],
type: data["matches"][0]["competition"]['type'],
emblem: data["matches"][0]["competition"]['emblem'],
);
}
}
the code work properly, every time index [0] change the coming data change for the next competition details
i want to make this index change automatically for fetching all data at one time, this index represent list data["matches"].length
My Api service look like
class ServiceApi {
Future<Competition > getmatches() async {
http.Response response = await http.get(
Uri.parse('_url'),
headers: {'X-Auth-Token': '_key'});
String body = response.body;
Map<String, dynamic> data = jsonDecode(body);
Competition compitition = Competition.fromJson(data);
int numberOfCompetition = data["matches"].length;
return matches;
}
}
You can map it like this
List<Competition> compititionList = data['matches'].map((item) => Competition.fromJson(item));
print(compittionList[0].name);
Btw theres a typo(spelling mistake) in competition (just incase you want to fix it)
And thr model should be
class Competition {
int id;
String name;
String code;
String type;
String emblem;
Competition({
required this.id,
required this.name,
required this.code,
required this.type,
required this.emblem,
});
factory Competition.fromJson(Map<String, dynamic> data) {
return Competition(
id: data["competition"]['id'],
name: data["competition"]['name'],
code: data["competition"]['code'],
type: data["competition"]['type'],
emblem: data["competition"]['emblem'],
);
}
}

Flutter - Converting Json map of a map to List<Object> in flutter

I am trying to de-serialize json in a parent class. One of my items is a Map of a Map, which I'd like to de-serialize into a Types class. I am struggling with parsing this because of the nested map in a map and I'm unclear on the proper syntax. At the end of the day I want a List in the parent class. The items within the types json block are dynamic, so there could be a type of critical, notice, etc. with varying descriptions.
Json sample:
{
"types":{
"alert":{
"description":"Action item."
},
"question":{
"description":"Select an applicable response."
},
"info":{
"description":"This is an information message, no action required."
}
}
}
Types class:
class Types {
final String name;
final String description;
Types({
required this.name,
required this.description,
});
factory Types.fromJson(String id, Map<String, dynamic> json) {
return Types(
name: id,
description: json['description'] == null ? '' : json['description'],
);
}
}
Parent class:
class Parent {
final String id;
final String name;
final String description;
final Features features;
final List<Types> types;
final List<String> users;
Parent({
required this.id,
required this.name,
required this.description,
required this.features,
required this.types,
required this.users,
});
factory Parent.fromJson( Map<String, dynamic> json) {
return Parent(
id: json['id'] == null ? '' : json['id'],
name: json['name'] == null ? '' : json['name'],
description: json['description'] == null ? '' : json['description'],
features: json['features'] == null
? Features()
: Features.fromJson(json['features']),
types: json['types'] == null ? [] : // ??? How to deserialize Map{Map{}} ,
users: json['users'] == null ? [] : List<String>.from(json['users']),
);
}
}
Any and all help is appreciated. Likewise if there is a better way to store this data I am open to that. The types class allows me to add future fields to it if necessary.
Thank you.
The general idea is to loop over each key/value pair in json['types'] and create an instance of Types for each one.
import 'dart:convert';
void main(List<String> args) {
final json = jsonDecode('''
{
"id": "test id",
"name": "test name",
"description": "test description",
"types":{
"alert":{
"description":"Action item."
},
"question":{
"description":"Select an applicable response."
},
"info":{
"description":"This is an information message, no action required."
}
}
}
''');
print(Parent.fromJson(json));
}
class Parent {
final String id;
final String name;
final String description;
final List<Types> types;
// ignoring features and users fields
Parent({
required this.id,
required this.name,
required this.description,
required this.types,
});
// prefer initializer lists to factory constructors
// when you are only creating instances of the same class
//
// also prefer:
// json['id'] ?? ''
// to:
// json['id'] == null ? '' : json['id']
//
Parent.fromJson(Map<String, dynamic> json)
: id = json['id'] ?? '',
name = json['name'] ?? '',
description = json['description'] ?? '',
// json['types'] is a map so you will have to loop
// over each of its entries (key/value pairs) and
// instantiate a new Types class for each entry.
types = [
for (final entry in (json['types'] ?? {}).entries)
Types.fromJson(entry.key, entry.value),
];
#override
String toString() =>
'Parent(id: $id, name: $name, description: $description, types: $types)';
}
class Types {
final String name;
final String description;
Types({
required this.name,
required this.description,
});
Types.fromJson(String id, Map<String, dynamic> json)
: name = id,
description = json['description'] ?? '';
#override
String toString() => 'Types(name: $name, description: $description)';
}

Trying to fetch json data in flutter

I am trying to fetch json data from this url- "https://jsonplaceholder.typicode.com/photos". And I am following this flutter cookbook tutorial - "https://flutter.dev/docs/cookbook/networking/background-parsing"
My model class looks like this-
class ModelData {
ModelData({
this.albumId,
this.id,
this.title,
this.url,
this.thumbnailUrl,
});
final int albumId;
final int id;
final String title;
final String url;
final String thumbnailUrl;
factory ModelData.fromJson(Map<String, dynamic> json) => ModelData(
albumId: json["albumId"] as int,
id: json["id"] as int,
title: json["title"] as String,
url: json["url"] as String,
thumbnailUrl: json["thumbnailUrl"] as String,
);
}
And my parseData method looks like this-
List<ModelData> parseData(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed
.map<ModelData>((json) => ModelData().fromJson(json)).toList();
}
The problem is in the last line of this method. It says "error: The method 'fromJson' isn't defined for the type 'ModelData'. (undefined_method at [flutter_rest] lib\main.dart:61)". i don't see any typo problem here. What might going wrong here?
Factory methods act like a static method but you are initialising the class by using ModelData().
Try like this:
ModelData.fromJson(json)

Null-safety for fromJson like methods

I want to define a simple class model UserResponse in Flutter 2.0.5 and build a fromJson method attached to this class to create an instance easily after receiving the data from the backend in json format.
class UserResponse {
String name;
UserResponse ({
required this.name,
});
UserResponse.fromJson(Map<String, dynamic> json) {
name= json['name'].toString();
}
}
The dart compiler however throws an error here:
dart(not_initialized_non_nullable_instance_field)
Furthermore:
Non-nullable instance field 'name' must be initialized.
Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.
If I know that I will only call the fromJson method if I have all the required data, how should I create the new Instance in this method? I don't want to change the name field in the class to late.
Use a factory constructor.
class UserResponse {
final String name;
UserResponse({
required this.name,
});
factory UserResponse.fromJson(Map<String, dynamic> json) {
return UserResponse(name: json['name'].toString());
}
}
For null-safety. You need to be check null right way. And front-end need handle server don't return this key, we need mock data and sure app can't crash.
class UserResponse {
UserResponse({
this.name,
});
final String? name;
factory UserResponse.fromRawJson(String str) =>
UserResponse.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory UserResponse.fromJson(Map<String, dynamic> json) => UserResponse(
name: json["name"] == null ? null : json["name"].toString(),
);
Map<String, dynamic> toJson() => {
"name": name == null ? null : name,
};
}
According to this very similar question there are mainly to ways:
Use an initializer list for the method
Use a factory method
Thus,
UserResponse.fromJson(Map<String, dynamic> json) :
name= json['name'] as String;
or
factory UserResponse.fromJson(Map<String, dynamic> json) {
return UserResponse(
name: json['name'] as String,
);
}

Parse json array without names in Dart

I cannot parse such json
[{"operation_id":"38911","external_id":null,"status":"SUCCESS","date":"2019-12-01T12:30:08.000Z","amount":200}]
The problem lies in array with dynamic names. Here's my POJO:
class PaymentHistoryResponse {
final List<History> list;
PaymentHistoryResponse({this.list});
}
class History {
final String operationId;
final dynamic externalId;
final String status;
final DateTime date;
final int amount;
History({
#required this.operationId,
#required this.externalId,
#required this.status,
#required this.date,
#required this.amount
});
factory History.fromJson(String str) => History.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory History.fromMap(Map<String, dynamic> json) => History(
operationId: json["operation_id"],
externalId: json["external_id"],
status: json["status"],
date: DateTime.parse(json["date"]),
amount: json["amount"]
);
Map<String, dynamic> toMap() => {
"operation_id": operationId,
"external_id": externalId,
"status": status,
"date": date.toIso8601String(),
"amount": amount
};
}
I also receive other json containing arrays, but named ones and I was able to decode them. How can I convert this one? P.s I've also made some research through this site and found some quite similar questions but a bit different and it didn't help me.
Since this is an array and not just a JSON you will need to do something like this:
mList = List<UserModel>.from(response.data.map((i) => UserModel.fromJson(i)));
Hint: for generating models with toJson and fromJson use this website:
https://javiercbk.github.io/json_to_dart/