Convert a class into JSON or List - dart

How to convert this class into JSON or List?
class cliente {
int id;
String nome;
String apelido;
String sexo;
String status;
}
Edit
I'm changed my class and works fine to my case:
class client {
Map<String, dynamic> fields => {
"id": "",
"name": "",
"nickname": "",
"sex": "",
"status": "",
}
Then I use:
client.fields["id"] = 1;
client.fields["name"] = "matheus";
sqlite.rowInsert("insert into client(id, name)", client.fields.Keys.toList(), client.fields.Values.toList());

Just create a method inside your class and return a Map<String, dynamic>
class cliente {
int id;
String nome;
String apelido;
String sexo;
String status;
Map<String, dynamic> toJson() => {
'id': id,
'nome': nome,
'apelido': apelido,
'sexo': sexo,
'status': status,
};
}
And use it for example :
final dataObject = new client();
...fill your object
final jsonData = dataObject.toJson();
Also you can try using this package to avoid writing all of your fields : https://pub.dartlang.org/packages/json_serializable

Related

Dart parse json map with json_serializable, but with the key

Suppose I have the following json (structured as <String key, Map value>):
{
'A1': {'name': 'a'},
'B2': {'name': 'b'}
}
and I want to parse it to this class (notice that I use the key as the id for that user), using the fromJson factory method, which accepts two arguments:
Class User {
final String id;
final String name;
factory User.fromJson(Map<String, dynamic> json, String key) {
return User(
id: key,
name: json['name'],
);
}
}
Can I achieve it using json_serializable ?
The json Map expected by this factory method is just the values of the top-level JSON object you're parsing.
All you need to do is parse the JSON, extract all keys, then pass the values to the factory method.
Something like this:
import 'dart:convert';
const json = '''
{
"A1": {"name": "a"},
"B2": {"name": "b"}
}
''';
class User {
final String id;
final String name;
User({required this.id, required this.name});
factory User.fromJson(Map<String, dynamic> json, String key) {
return User(
id: key,
name: json['name'],
);
}
#override
String toString() => 'User(id=$id, name=$name)';
}
main() {
final map = jsonDecode(json);
map.forEach((id, userJson) {
final user = User.fromJson(userJson, id);
print(user);
});
}
Prints:
User(id=A1, name=a)
User(id=B2, name=b)
Now, to use json_serializable, just annotate it and replace your implementation with the generated one...
#JsonSerializable()
class User {
...
factory User.fromJson(Map<String, dynamic> json, String key) =>
// pass in only the relevant json Map!
_$UserFromJson(json[key]);
}

failed due to: Bad state: No builder factory for BuiltList

I am using builtvalue for my PODO class
Following is my json response
{
"status": 1,
"msg": "Success",
"allotmentMasterID": "1",
"allotmentInfoID": "1",
"category": [
{
"categoryID": "1",
"categoryName": "Major",
"selectedCount": "0",
"status": 1
},
{
"categoryID": "2",
"categoryName": "Mandatory",
"selectedCount": "0",
"status": 0
},
{
"categoryID": "3",
"categoryName": "Minor",
"selectedCount": "0",
"status": 0
}
]
}
I have created a built value for this
Following are the classes
library specialisation_model_first_screen;
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
part 'specialisation_model_first_screen.g.dart';
abstract class SpecialisationModelFirstScreen
implements
Built<SpecialisationModelFirstScreen,
SpecialisationModelFirstScreenBuilder> {
SpecialisationModelFirstScreen._();
factory SpecialisationModelFirstScreen(
[updates(SpecialisationModelFirstScreenBuilder b)]) =
_$SpecialisationModelFirstScreen;
#nullable
#BuiltValueField(wireName: 'status')
int get status;
#nullable
#BuiltValueField(wireName: 'msg')
String get msg;
#nullable
#BuiltValueField(wireName: 'allotmentMasterID')
String get allotmentMasterID;
#nullable
#BuiltValueField(wireName: 'allotmentInfoID')
String get allotmentInfoID;
#nullable
#BuiltValueField(wireName: 'category')
BuiltList<Category> get category;
static Serializer<SpecialisationModelFirstScreen> get serializer =>
_$specialisationModelFirstScreenSerializer;
}
abstract class Category implements Built<Category, CategoryBuilder> {
Category._();
factory Category([updates(CategoryBuilder b)]) = _$Category;
#nullable
#BuiltValueField(wireName: 'categoryID')
String get categoryID;
#nullable
#BuiltValueField(wireName: 'categoryName')
String get categoryName;
#nullable
#BuiltValueField(wireName: 'selectedCount')
String get selectedCount;
#nullable
#BuiltValueField(wireName: 'status')
int get status;
static Serializer<Category> get serializer => _$categorySerializer;
}
library serializers;
import 'package:built_value/serializer.dart';
part 'package:dice_clutter/models/serializers/serializers.g.dart';
#SerializersFor(const [SpecialisationModelFirstScreen])
Serializers serializers = _$serializers;
Serializers standardSerializers = (serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();
Following is my serializers.g.dart file
part of serializers;
Serializers _$serializers = (new Serializers().toBuilder()
..add(SpecialisationModelFirstScreen.serializer))
.build();
When i am making an api request i am getting the response correctly but following error is thrown
failed due to: Bad state: No builder factory for BuiltList<Category>. Fix by adding one, see SerializersBuilder.addBuilderFactory.
Is this a bug in build value library itself or am i doing something wrong?
In some cases - and I do not fully understand specific reasons - my objects fail to deserialize with StandartJsonPlugin.
I had to edit my serializers.g.dart file as follows
Serializers _$serializers = (new Serializers().toBuilder()
..add(SpecialisationModelFirstScreen.serializer)
..add(Category.serializer)
..addBuilderFactory(
const FullType(
BuiltList, const [const FullType(Category)]),
() => new ListBuilder<Category>())
)
.build();
Thanks to Tensor Programming Video on Youtube
There is some bug in the builtvalue library as it is not able to generate serializers.g.dart properly in some cases. Hope It gets resolved in the future
You need to add the Category class to the list of classes that can be serialized:
#SerializersFor(const [
SpecialisationModelFirstScreen,
Category, <-- Category available for serialization
])
then regenerate your built_value classes.
More details can be found in this answer
base on JSON and serialization - Flutter and your code ,
you are missing fromJson ,
using JSON to Dart
see the fromJson function
class Autogenerated {
int status;
String msg;
String allotmentMasterID;
String allotmentInfoID;
List<Category> category;
Autogenerated(
{this.status,
this.msg,
this.allotmentMasterID,
this.allotmentInfoID,
this.category});
Autogenerated.fromJson(Map<String, dynamic> json) {
status = json['status'];
msg = json['msg'];
allotmentMasterID = json['allotmentMasterID'];
allotmentInfoID = json['allotmentInfoID'];
if (json['category'] != null) {
category = new List<Category>();
json['category'].forEach((v) {
category.add(new Category.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
data['msg'] = this.msg;
data['allotmentMasterID'] = this.allotmentMasterID;
data['allotmentInfoID'] = this.allotmentInfoID;
if (this.category != null) {
data['category'] = this.category.map((v) => v.toJson()).toList();
}
return data;
}
}
class Category {
String categoryID;
String categoryName;
String selectedCount;
int status;
Category(
{this.categoryID, this.categoryName, this.selectedCount, this.status});
Category.fromJson(Map<String, dynamic> json) {
categoryID = json['categoryID'];
categoryName = json['categoryName'];
selectedCount = json['selectedCount'];
status = json['status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['categoryID'] = this.categoryID;
data['categoryName'] = this.categoryName;
data['selectedCount'] = this.selectedCount;
data['status'] = this.status;
return data;
}
}

Need help to parsing JSON in Flutter

I am trying to get data from the internet in Flutter.
But I am getting an error on JSON parsing.
Can anyone tell me what is the problem?
I am trying to get data from this URL
https://swapi.co/api/starships/
Example JSON
{
"count": 37,
"next": "https://swapi.co/api/starships/?page=2",
"previous": null,
"results": [
{
"name": "Executor",
"model": "Executor-class star dreadnought",
"manufacturer": "Kuat Drive Yards, Fondor Shipyards",
"cost_in_credits": "1143350000",
"length": "19000",
"max_atmosphering_speed": "n/a",
"crew": "279144",
"passengers": "38000",
"cargo_capacity": "250000000",
"consumables": "6 years",
"hyperdrive_rating": "2.0",
"MGLT": "40",
"starship_class": "Star dreadnought",
"pilots": [],
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/3/"
],
"created": "2014-12-15T12:31:42.547000Z",
"edited": "2017-04-19T10:56:06.685592Z",
"url": "https://swapi.co/api/starships/15/"
},
]
}
Model class
class RestModel {
final String name;
final String model;
final String manufacturer;
final String cost_in_credits;
final String length;
final String max_atmosphering_speed;
final String crew;
final String passengers;
final String cargo_capacity;
final String consumables;
final String hyperdrive_rating;
final String MGLT;
final String starship_class;
final List films;
final String pilots;
final String created;
final String edited;
final String url;
RestModel(
{this.name,
this.model,
this.manufacturer,
this.cost_in_credits,
this.length,
this.max_atmosphering_speed,
this.crew,
this.passengers,
this.cargo_capacity,
this.consumables,
this.hyperdrive_rating,
this.MGLT,
this.starship_class,
this.films,
this.pilots,
this.created,
this.edited,
this.url});
factory RestModel.fromJson(Map<String, dynamic> json) {
return RestModel(
name: json["name"],
model: json["model"],
manufacturer: json["manufacturer"],
cost_in_credits: json["cost_in_credits"],
max_atmosphering_speed: json["max_atmosphering_speed"],
crew: json["crew"],
passengers: json["passengers"],
cargo_capacity: json["cargo_capacity"],
consumables: json["consumables"],
hyperdrive_rating: json["hyperdrive_rating"],
MGLT: json["MGLT"],
starship_class: json["starship_class"],
films: json["flims"],
pilots: json["pilots"],
created: json["created"],
edited: json["edited"],
url: json["url"],
);
}
}
and the Flutter code is:
final link = "https://swapi.co/api/starships/";
List<RestModel> list;
Future getData() async {
var res = await http
.get(Uri.encodeFull(link), headers: {"Accept":"application/json"});
if (res.statusCode == 200) {
var data = json.decode(res.body);
var rest = data["results"];
for (var model in rest) {
list.add(RestModel.fromJson(model));
}
print("List Size: ${list.length}");
}
}
The main problem is when it tries to fill data from JSON.
RestModel.fromJson(model)
so what I have to change to fix this problem.
Try to cast the data 'results' to List , like this :
var rest = data["results"] as List;
Updated
Now that we know the error log: "No static method 'fromJson' declared in class 'RestModel'"
It's because you are using a static method in this line:
list.add(RestModel.fromJson(model));
You must change the call in order to use the factory constructor, like this :
list.add(new RestModel.fromJson(model));

FireStore and Flutter

I am writing an android app with flutter and Firestore at the backend database.
I can add single data to Firestore, but when I add an object with the nested object it fails. can't find any example or solution on google.
please help.
below is my code,
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:json_annotation/json_annotation.dart';
part 'Inspection.g.dart';
//run code => flutter packages pub run build_runner build
#JsonSerializable()
class Inspection extends Object with _$InspectionSerializerMixin {
Inspection(
{this.inspectionDate,
this.staffName,
this.arrivedTime,
this.leaveTime,
this.foundLocation,
this.postName,
this.guestsProportion,
this.situationRemark,
this.userid,
this.id,
this.grooming});
String id;
#JsonSerializable(nullable: false)
DateTime inspectionDate;
#JsonSerializable(nullable: false)
String arrivedTime;
#JsonSerializable(nullable: false)
String leaveTime;
#JsonSerializable(nullable: false)
String staffName;
#JsonSerializable(nullable: false)
String postName;
#JsonSerializable(nullable: false)
String foundLocation;
#JsonSerializable(nullable: false)
String guestsProportion;
#JsonSerializable(nullable: false)
String situationRemark;
#JsonKey(nullable: false)
String userid;
#JsonKey(nullable: false)
Grooming grooming;
static Inspection fromDocument(DocumentSnapshot document) =>
new Inspection.fromJson(document.data);
factory Inspection.fromJson(Map<String, dynamic> json) =>
_$InspectionFromJson(json);
}
#JsonSerializable()
class Grooming extends Object {
int groomingScore;
int hairScore;
int uniformScore;
int decorationScore;
int maskWearScore;
int maskCleanScore;
Grooming();
factory Grooming.fromJson(Map<String, dynamic> json) =>
_$GroomingFromJson(json);
}
and this is generated by build_runner
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'Inspection.dart';
// **************************************************************************
// Generator: JsonSerializableGenerator
// **************************************************************************
Inspection _$InspectionFromJson(Map<String, dynamic> json) => new Inspection(
inspectionDate: json['inspectionDate'] == null
? null
: DateTime.parse(json['inspectionDate'] as String),
staffName: json['staffName'] as String,
arrivedTime: json['arrivedTime'] as String,
leaveTime: json['leaveTime'] as String,
foundLocation: json['foundLocation'] as String,
postName: json['postName'] as String,
guestsProportion: json['guestsProportion'] as String,
situationRemark: json['situationRemark'] as String,
userid: json['userid'] as String,
id: json['id'] as String,
grooming: new Grooming.fromJson(json['grooming'] as Map<String, dynamic>));
abstract class _$InspectionSerializerMixin {
String get id;
DateTime get inspectionDate;
String get arrivedTime;
String get leaveTime;
String get staffName;
String get postName;
String get foundLocation;
String get guestsProportion;
String get situationRemark;
String get userid;
Grooming get grooming;
Map<String, dynamic> toJson() => <String, dynamic>{
'id': id,
'inspectionDate': inspectionDate?.toIso8601String(),
'arrivedTime': arrivedTime,
'leaveTime': leaveTime,
'staffName': staffName,
'postName': postName,
'foundLocation': foundLocation,
'guestsProportion': guestsProportion,
'situationRemark': situationRemark,
'userid': userid,
'grooming': grooming
};
}
Grooming _$GroomingFromJson(Map<String, dynamic> json) => new Grooming()
..groomingScore = json['groomingScore'] as int
..hairScore = json['hairScore'] as int
..uniformScore = json['uniformScore'] as int
..decorationScore = json['decorationScore'] as int
..maskWearScore = json['maskWearScore'] as int
..maskCleanScore = json['maskCleanScore'] as int;
abstract class _$GroomingSerializerMixin {
int get groomingScore;
int get hairScore;
int get uniformScore;
int get decorationScore;
int get maskWearScore;
int get maskCleanScore;
Map<String, dynamic> toJson() => <String, dynamic>{
'groomingScore': groomingScore,
'hairScore': hairScore,
'uniformScore': uniformScore,
'decorationScore': decorationScore,
'maskWearScore': maskWearScore,
'maskCleanScore': maskCleanScore
};
}
code used to insert data
Future<bool> addInspection(Inspection item) async {
print('creating');
var newdoc = await inspectionCollection.document().get();
item.id = newdoc.documentID;
item.userid = user.uid;
inspectionCollection.add(item.toJson()).then((onValue) {
onValue.setData({'id': onValue.documentID});
}).catchError((error) {
print(error.toString());
});

Dart Convert List as Map Entry for JSON Encoding

I asked a question before about Dart encoding/decoding to JSON, however, the libraries that were suggested were not complete and I decided to manually handle that.
The objective is to convert these objects to a map.
class Parent extends Object {
int id;
String name;
List<Child> listChild = new List<Child>();
Map toMap() => {"id":id, "name":name, "listChild":listChild};
}
class Child extends Object {
int id;
String childName;
Map toMap() => {"id":id, "childName":childName};
}
When doing
print(JSON.encode(parent.toMap()));
I am seeing it go here, any suggestion how to make this work?
if (!stringifyJsonValue(object)) {
checkCycle(object);
try {
var customJson = _toEncodable(object);
if (!stringifyJsonValue(customJson)) {
throw new JsonUnsupportedObjectError(object);
}
_removeSeen(object);
} catch (e) {
throw new JsonUnsupportedObjectError(object, cause : e);
}
}
}
Map toMap() => {"id":id, "name":name: "listChild": listChild.map((c) => c.toJson().toList())};
is valid for JSON.
import 'dart:convert' show JSON;
...
String json = JSON.encode(toMap());
You can also use the toEncodeable callback - see How to convert DateTime object to json
If your class structure does not contain's any inner class then follow
class Data{
String name;
String type;
Map<String, dynamic> toJson() => {
'name': name,
'type': type
};
}
If your class uses inner class structure
class QuestionTag {
String name;
List<SubTags> listSubTags;
Map<String, dynamic> toJson() => {
'name': name,
'listSubTags': listSubTags.map((tag) => tag.toJson()).toList()
};
}
class SubTags {
String tagName;
String tagDesc;
SubTags(this.tagName, this.tagDesc);
Map<String, dynamic> toJson() => {
'tagName': tagName,
'tagDesc': tagDesc,
};
}
Just rename Map toMap() into Map toJson() and it will work fine. =)
void encode() {
Parent p = new Parent();
Child c1 = new Child();
c1 ..id = 1 ..childName = "Alex";
Child c2 = new Child();
c2 ..id = 2 ..childName = "John";
Child c3 = new Child();
c3 ..id = 3 ..childName = "Jane";
p ..id = 1 ..name = "Lisa" ..listChild = [c1,c2,c3];
String json = JSON.encode(p);
print(json);
}
class Parent extends Object {
int id;
String name;
List<Child> listChild = new List<Child>();
Map toJson() => {"id":id, "name":name, "listChild":listChild};
}
class Child extends Object {
int id;
String childName;
Map toJson() => {"id":id, "childName":childName};
}

Resources