Equatable

Flutter == vs Value Equality code import 'package:equatable/equatable.dart'; class Contact extends Equatable { const Contact({required this.type, required this.value}); final String type; final String value; @override List<Object?> get props => [type, value]; } class Phone with Equatable { const Phone({this.isPrimary = false, this.contact}); final bool isPrimary; final Contact? contact; @override List<Object?> get props => [...contact?.props ?? [], isPrimary]; } void main() { Contact a = Contact(type: "phone", value: "0101"); Contact b = Contact(type: "phone", value: "0101"); if (a == b) { print("same same ...."); } else { print("a: ${a.toString()}"); print("b: ${b.toString()}"); } } equatable on pub.dev↗

Json serilizable

user.dart import 'package:example/models/contact.dart'; import 'package:json_annotation/json_annotation.dart'; part 'user.g.dart'; // the `user` is the fileName @JsonEnum(valueField: "value") enum Gender { male("m"), female("f"); const Gender(this.value); final String value; } @JsonSerializable(fieldRename: FieldRename.screamingSnake) class User { User({ required this.name, required this.dateOfBirth, required this.gender, required this.contact, required this.presentAddress, }); final String name; final Gender gender; @JsonKey(name: "dob") final DateTime? dateOfBirth; final Contact contact; final String presentAddress; factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(this); } Custom Converter class DateTimeConverter implements JsonConverter<DateTime?, Map<String, dynamic>?> { const DateTimeConverter(); @override DateTime? fromJson(Map<String, dynamic>? json) { if (json == null) return null; final second = json["seconds"]; return DateTime.fromMillisecondsSinceEpoch(second); } @override Map<String, dynamic>? toJson(DateTime? object) { if (object == null) return null; return {'seconds': (object.millisecondsSinceEpoch / 1000).round()}; } } Custom config build.yaml targets: $default: builders: json_serializable: options: # Options configure how source code is generated for every # `@JsonSerializable`-annotated class in the package. # # The default value for each is listed. any_map: false checked: false constructor: "" create_factory: true create_field_map: false create_json_keys: false create_json_schema: true create_per_field_to_json: false create_to_json: true date_time_utc: true disallow_unrecognized_keys: false explicit_to_json: false field_rename: snake generic_argument_factories: false ignore_unannotated: false include_if_null: true json_serializable on pub.dev↗

freezed

Flutter Freezed | Models, copyWith, JSON Serialization, Generics & Union Types Make sure to watch json_seriliazble first. Freezed class address.dart { "success": true, "data": { "street": "123 Main Street", "district": "Dhaka", "country": "Bangladesh" }, "message": "Address fetched" } import 'package:freezed_annotation/freezed_annotation.dart'; part 'address.freezed.dart'; part 'address.g.dart'; @freezed abstract class Address with _$Address { const factory Address({ required String street, required String district, required String country, }) = _Address; factory Address.fromJson(Map<String, Object?> json) => _$AddressFromJson(json); static const Address present = Address( street: "present", district: "addr.dis", country: "BD", ); static const Address permanent = Address( street: "permanent", district: "addr.dis", country: "...", ); } person.dart { "success": true, "data": { "name": "John Doe", "age": 25, "address": "Earth", "skills": ["Dart", "Flutter"], "presentAddress": { "street": "123 Main Street", "district": "Dhaka", "country": "Bangladesh" }, "permanentAddress": { "street": "45 Lake Road", "district": "Chattogram", "country": "Bangladesh" } }, "message": "Person fetched" } import 'package:freezed_annotation/freezed_annotation.dart'; import 'address.dart'; part 'user.freezed.dart'; part 'user.g.dart'; @freezed abstract class Person with _$Person { const factory Person({ required String name, int? age, @Default("Eath") String? address, @Default([]) List<String> skills, required Address presentAddress, Address? permanentAddress, }) = _Person; factory Person.fromJson(Map<String, Object?> json) => _$PersonFromJson(json); static const Person ui = Person( name: "0", age: 0, skills: [], presentAddress: Address.present, permanentAddress: Address.permanent, ); } Generic api_response.dart import 'package:freezed_annotation/freezed_annotation.dart'; part 'api_response.freezed.dart'; part 'api_response.g.dart'; @Freezed(genericArgumentFactories: true) abstract class ApiResponse<T> with _$ApiResponse<T> { const factory ApiResponse({ required bool success, T? data, String? message, }) = _ApiResponse<T>; factory ApiResponse.fromJson( Map<String, dynamic> json, T Function(Object?) fromJsonT, ) => _$ApiResponseFromJson(json, fromJsonT); } Union code-snippet We are using type instead of runtimetype ...