Is your feature request related to a problem? Please describe.
I have a class like this:
class Orgs {
final String organizationId;
final User user;
}
I've already manually create a TypeAdapter for User. However, how can I create TypeAdapter for Orgs? Because the BinaryWriter don't have any method to write a custom object except primitive type or list.
Describe the solution you'd like
I would like to be able to manually create TypeAdapter for class with class inside.
Version
You are not right, hive working perfect with custom types instead of primitives. Check generated files for Orgs, or create it, and register adapters, good luck =)
@Renesanse Oh, really? I haven't try generated files yet because I create it manually. However in BinaryWriter I don't see any method to write for TypeAdapter-compatible object (in my case is User). Could you tell me that method?
Edit 1: It seems that's method write.write(). Let me try it first.
You need to follow the docs and generate a TypeAdapter. There is no method to write objects since each object consists of primitives and other objects.
Hive writes all the fields individually. Take a look at the generated TypeAdapter.
working fine
@HiveType()
class Source {
@HiveField(0)
final String id;
@HiveField(1)
final String name;
@HiveType()
class Article {
@HiveField(0)
final Source source;
@HiveField(1)
What if the class belongs to an external package/library,
how do i make a type adapter for that e.g the Source class in the example you gave. I was thinking inheritance but that doesn't work
I'm working on support for inheritance. You can already create a custom TypeAdapter.
For the Source class:
class SourceAdapter extends TypeAdapter<Source> {
@override
Source read(BinaryReader reader) {
return Source()
..id = reader.read()
..name = reader.read();
}
void write(BinaryWriter writer, Source obj) {
writer.write(obj.id);
writer.write(obj.name);
}
}
Hello, how can I register a TypeAdapter for an external class that belong to a flutter package?
Example: I have a image_picker_web package, and I use the MediaInfo as data type, how can I register MediaInfo?
Hello, how can I register a TypeAdapter for an external class that belong to a flutter package?
Example: I have a image_picker_web package, and I use the MediaInfo as data type, how can I register MediaInfo?
Im also wondering the same thing. Need an adapter for GeoPoint
Hello, how can I register a TypeAdapter for an external class that belong to a flutter package?
Example: I have a image_picker_web package, and I use the MediaInfo as data type, how can I register MediaInfo?
Up
Hello, how can I register a TypeAdapter for an external class that belong to a flutter package?
Example: I have a image_picker_web package, and I use the MediaInfo as data type, how can I register MediaInfo?
Yes! You can create TypeAdapter for any class you want! (You will need to write serialization part yourself but It's actually very easy). For example here's a type adapter from our internal code:
import 'package:hive/hive.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:flutter_google_maps/flutter_google_maps.dart';
/// Used for stores geographic location
class GeoCoordinate {
const GeoCoordinate(this.x, this.y);
/// [GeoCoordinate] with (0, 0) value
static const GeoCoordinate zero = const GeoCoordinate(0, 0);
/// Latitude
final double x;
/// Longitude
final double y;
@override
String toString() => '$x,$y';
GeoCoord toGoogleMapsUnit() => GeoCoord(x, y);
/// Parse coordinates from [source]. Throws [FormatException] if passed
/// [source] value is invalid. You can use [tryParse] if you don't want
/// to catch exception.
factory GeoCoordinate.parse(String source) {
if (source == null) {
return null;
}
List<double> parts = source.split(',').map(double.parse).toList();
if (parts.length != 2) {
throw FormatException('Invalid value supplied for parsing coordinate.');
}
return GeoCoordinate(parts[0], parts[1]);
}
/// Parses coordinates from [source]. Returns null if parsing failed.
static GeoCoordinate tryParse(String source) {
try {
return GeoCoordinate.parse(source);
} on FormatException catch (_) {
return null;
}
}
factory GeoCoordinate.fromJson(dynamic json) {
if (json is List) {
return GeoCoordinate(json[0], json[1]);
} else if (json is Map) {
return GeoCoordinate(json['lat'], json['lng']);
} else if (json is String) {
return GeoCoordinate.parse(json);
} else {
throw FormatException(
'Unable to convert ${json.runtimeType.toString()} to GeoCoordinate.');
}
}
}
class GeoCoordinateConverter implements JsonConverter<GeoCoordinate, String> {
const GeoCoordinateConverter();
@override
GeoCoordinate fromJson(String json) => GeoCoordinate.parse(json);
@override
String toJson(GeoCoordinate object) => object.toString();
}
class GeoCoordinateAdapter extends TypeAdapter<GeoCoordinate> {
@override
final int typeId = 1;
@override
GeoCoordinate read(BinaryReader reader) {
var x = reader.readDouble();
var y = reader.readDouble();
return GeoCoordinate(x, y);
}
@override
void write(BinaryWriter writer, GeoCoordinate obj) {
writer.writeDouble(obj.x);
writer.writeDouble(obj.y);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is GeoCoordinateAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
Most helpful comment
I'm working on support for inheritance. You can already create a custom TypeAdapter.
For the
Sourceclass: