#JsonSerializable
class PatchUserDTO {
final String? name;
final DateTime? birthday;
...OTHER STAFF...
}
But I need to differentiate between birthday == null and birthday is not set.
I guess, nice solution would be
class Optional<T> {
final T? value;
Optional(this.value);
T? toJson() => value;
}
#JsonSerializable
class PatchUserDTO {
final String? name;
#JsonKey(includeIfNull: false)
final Optional<DateTime>? birthday;
...OTHER STAFF...
}
But includeIfNull is applied to finalised json. So if Optional<DateTime> is not null, but value is null, it still won't be serialized.
Related
For example, JSON looks like this:
{
"id": 12151,
"cadastres":[
{
"general_info": {
"area": 1515,
"datev": "20.12.20"
}
},
{
"general_info": {
"area": 1151,
"datev": "10.12.10"
}
}
]
}
I want to get each of these values.
I created a model:
class Cadastre {
final int id;
final double area;
final String creationDate;
Cadastre(
{required this.id,
required this.area,
required this.creationDate});
factory Cadastre.fromJson(Map<String, dynamic> map) {
return Cadastre(
id: map['id'],
area: map['area'],
creationDate: map['datev'],);
}
}
In this way, I would get only the ID correctly, how can I get data for the model from an object nested in an array?
Your JSON returns an id and a list of cadastre objects. If you want to have a reference of the id in each model, I will suggest this implementation:
class Cadastre {
final int id;
final double area;
final String creationDate;
Cadastre({
required this.id,
required this.area,
required this.creationDate,
});
/*
You will use it like this:
final cadastres = Cadastre.fromJsonList(json['id'], json['cadastres']);
*/
static List<Cadastre> fromJsonList(int id, List<Map<String, dynamic>> list) {
return list.map((map) {
map.putIfAbsent("id", () => id);
return Cadastre.fromJson(map);
}).toList();
}
factory Cadastre.fromJson(Map<String, dynamic> map) {
return Cadastre(
id: map["id"],
area: map['area'],
creationDate: map['datev'],
);
}
}
int _code;
String _description;
String _unit;
int _price;
Products(this._code, this._description, this._unit, this._price);
factory Products.fromJSON(Map<String, dynamic> json) {
if (json == null) {
return null;
} else {
return Products(json['code'], json['description'], json['unit'],json['price']);
}
}
}
Here is my code i cant return the null because of an error. i coudnt get what the error was. please help how to re arrange this without error. explain further would be fine. thanks in advance
Prefer factories that do not return null.
class Products {
int _code;
String _description;
String _unit;
int _price;
Products(this._code, this._description, this._unit, this._price);
factory Products.fromJSON(Map<String, dynamic> json) {
return Products(
json['code'],
json['description'],
json['unit'],
json['price'],
);
}
}
But if you still want to verify if json is null, prefer a static method
class Products {
int _code;
String _description;
String _unit;
int _price;
Products(this._code, this._description, this._unit, this._price);
static Products? fromJSON(Map<String, dynamic>? json) {
if (json == null) {
return null;
} else {
return Products(json['code'], json['description'], json['unit'],json['price']);
}
}
}
The ? indicates that a Type can be null.
I have a class A that contains a list of objects of another class B(Composition). Now, I want to store the object of class A to sqlite database. I learnt how to encode basic strings or integers to json but still could not find a way to encode a list of objects.
Need to save an object of concrete 'Layout'.
class MallardDuck extends Duck {
var image = "https://image.shutterstock.com/image-vector/cartoon-duck-swimming-600w-366901346.jpg";
Widget d_widget;
List<Widget> previous_states = [];
List<Widget> redo_states = [];
}
abstract class Layout extends Duck{
List<Duck> listOfDucks = [];
bool default_layout;
}
This might help you.
It is not the answer to your specific case but hopefully this code will help you see how I did it in a different class.
class BlogData {
final String title;
final String associatedBusinessId;
final String category;
final List<BlogParagraph> blogParagraphs;
BlogData(
{this.title,
this.associatedBusinessId,
this.category,
this.blogParagraphs});
Map<String, dynamic> toJson() {
return {
'title': this.title,
'associatedBusinessId': this.associatedBusinessId,
'category': this.category,
'blogParagraphs':
blogParagraphs.map((paragraph) => paragraph.toJson()).toList()
};
}
}
Then, in the blog paragraphs class:
class BlogParagraph {
final int paragraphId;
final String content;
final Set<int> imageRefs;
BlogParagraph({this.paragraphId, this.content, this.imageRefs});
Map<String, dynamic> toJson() {
return {
'id': this.paragraphId,
'content': this.content,
'imageRefs': imageRefs.isEmpty ? [] : imageRefs.toList(),
};
}
}
I'm using automatic serialization/deserialization in dart like mentioned here
import 'package:json_annotation/json_annotation.dart';
part 'billing.g.dart';
#JsonSerializable()
class Billing {
Billing(){}
String _id;
String name;
String status;
double value;
String expiration;
factory Billing.fromJson(Map<String, dynamic> json) => _$BillingFromJson(json);
Map<String, dynamic> toJson() => _$BillingToJson(this);
}
But in order for the serialization/deserialization to work, the fields must be public. However, in Dart, a field with _ at the beggining is private. So I can't use _id from mongodb to serialize/deserialize things.
How can I overcome this?
You can use #JsonKey annotation. Refer https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/name.html
import 'package:json_annotation/json_annotation.dart';
part 'billing.g.dart';
#JsonSerializable()
class Billing {
Billing(){}
// Tell json_serializable that "_id" should be
// mapped to this property.
#JsonKey(name: '_id')
String id;
String name;
String status;
double value;
String expiration;
factory Billing.fromJson(Map<String, dynamic> json) => _$BillingFromJson(json);
Map<String, dynamic> toJson() => _$BillingToJson(this);
}
How can I convert an integer timestamp to Datetime.
Sample Code:
#JsonSerializable(nullable: false)
class Person {
final String firstName;
final String lastName;
final DateTime dateOfBirth;
Person({this.firstName, this.lastName, this.dateOfBirth});
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
Map<String, dynamic> toJson() => _$PersonToJson(this);
}
How do I convert dateOfBirth integer timeStamp to DateTime?
To convert an int timestamp to DateTime, you need to pass a static method that
returns a DateTime result to the fromJson parameter in the #JsonKey annotation.
This code solves the problem and allows the convertion.
#JsonSerializable(nullable: false)
class Person {
final String firstName;
final String lastName;
#JsonKey(fromJson: _fromJson, toJson: _toJson)
final DateTime dateOfBirth;
Person({this.firstName, this.lastName, this.dateOfBirth});
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
Map<String, dynamic> toJson() => _$PersonToJson(this);
static DateTime _fromJson(int int) => DateTime.fromMillisecondsSinceEpoch(int);
static int _toJson(DateTime time) => time.millisecondsSinceEpoch;
}
usage
Person person = Person.fromJson(json.decode('{"firstName":"Ada", "lastName":"Amaka", "dateOfBirth": 1553456553132 }'));
I use this:
#JsonSerializable()
class Person {
#JsonKey(fromJson: dateTimeFromTimestamp)
DateTime dateOfBirth;
...
}
DateTime dateTimeFromTimestamp(Timestamp timestamp) {
return timestamp == null ? null : timestamp.toDate();
}