Flutter Hive store color - flutter

I need to store colour in my Hive database to retrieve in my eCommerce Application,
it gave me the error below saying that I need to make an adapter, can anyone tell me how to make a colour adapter?
part 'items_model.g.dart';
#HiveType(typeId: 0)
class Item {
#HiveField(0)
final String name;
#HiveField(1)
final double price;
#HiveField(2)
final String? description;
#HiveField(3)
var image;
#HiveField(4)
final String id;
#HiveField(5)
final String shopName;
#HiveField(6)
final List<Category> category;
#HiveField(7)
Color? color;
#HiveField(8)
int? quantity;
Item({
required this.category,
required this.image,
required this.name,
required this.price,
this.description,
required this.id,
required this.shopName,
this.color,
required this.quantity,
});
}
does anyone know how to generate or create Color Adapter? as I don't know-how
E/flutter ( 4621): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: HiveError: Cannot write, unknown type: MaterialColor. Did you forget to register an adapter?

I think the easiest thing to do here would be to store the int value of the color.
Here's an example.
final colorValue = Colors.blue.value; // colorValue is an integer here
So your Hive color could be stored like this
#HiveField(7)
int? colorValue;
Then, in your app when you're creating a color from storage it would look like this.
final item = Item(...however you initialize your Item);
final color = Color(item.colorValue);

Base on previous answers by #Cryptozord and #Loren.A one can simply just write specific adapter for color
import 'package:flutter/cupertino.dart';
import 'package:hive/hive.dart';
class ColorAdapter extends TypeAdapter<Color> {
#override
final typeId = 221;
#override
Color read(BinaryReader reader) => Color(reader.readUint32());
#override
void write(BinaryWriter writer, Color obj) => writer.writeUint32(obj.value);
}
and remember to register your adapter with
Hive.registerAdapter(ColorAdapter());
make sure your typeId is not taken by other models
now you can use
#HiveField(7)
Color? colorValue;

I was confused about this for a whole day and I figured out how to do it. You should instead create your adapter manually like so:
class ItemAdapter extends TypeAdapter<Item> {
#override
final typeId = 0;
#override
ThemeState read(BinaryReader reader) {
return Item(
color: Color(reader.readUint32()),
//the rest of the fields here
);
}
#override
void write(BinaryWriter writer, ThemeState obj) {
writer.writeUint32(obj.color.value);
writer.writeString(obj.name);
//the rest of the fields here
}
}
Color needs to saved and written as a Uint32 value because the Int32 value only has a range of -2147483648 to 2147483647 and an unsigned integer is 0 to 4294967295. The integer values of Color() can go past 2147483647. If Uint32 is not used then your values will not be stored correctly and weird colors will be saved instead.

Related

how to target an element of our class with hive to change it

good morning,
I don't know how to access an element of my boxHive without rebuilding it
I would like to be able to update some information without changing the existing one
Here is how I do it here, I use the constructor of my model class to add notes but it rebuilds all my class at the same time I would like it to rebuild only ListNote
class InformationPatient extends StatefulWidget {
final Patients patients;
final int index;
const InformationPatient(this.patients, this.index, {Key? key})
: super(key: key);
#override
State<InformationPatient> createState() => _InformationPatientState();
}
class _InformationPatientState extends State<InformationPatient> {
late Box<Patients> boxPatient;
#override
void initState() {
super.initState();
boxPatient = Hive.box('Patient');
}
void _addNote(String newtitle, String newnote, String newconclusion) {
final newNOTE = Patients(
listOfNotes: [
ListNote(title: newtitle, note: newnote, conclusion: newconclusion)
],
);
boxPatient.put(widget.index, newNOTE);
Navigator.of(context).pop();
}
And here is my class model
import 'package:hive_flutter/hive_flutter.dart';
part 'listpatient.g.dart';
#HiveType(typeId: 0)
class Patients {
#HiveField(0)
final String? name;
#HiveField(1)
final String? firstname;
#HiveField(3)
final String? dateofbirth;
#HiveField(4)
final String? email;
#HiveField(5)
final String? phonenumber;
#HiveField(6)
final DateTime? date;
#HiveField(7)
final int? id;
#HiveField(8)
final List<ListNote>? listOfNotes;
const Patients({
this.name,
this.firstname,
this.dateofbirth,
this.email,
this.phonenumber,
this.date,
this.id,
this.listOfNotes,
});
}
#HiveType(typeId: 10)
class ListNote {
#HiveField(1)
final String? title;
#HiveField(2)
final String? note;
#HiveField(3)
final String? conclusion;
ListNote({
this.title,
this.note,
this.conclusion,
});
}
Actually Hive offers only Write and Read operations, as you can see from its official documentation for flutter
so in order to update an Object in your boxPatient Box you need to get it with this:
Patients patients = boxPatient.get(widget.index);
then make your edits over it, then save it again on that same key:
boxPatient.put(widget.index, patients);
you can say we just updated it with this process.

Provide generic arguments to DocumentReferences in JsonConverter

I'm using json_serializable's JSONConverter interface to convert Firestore's DocumentReferences into valid JSON objects.
This is the JSON converter class. It tries to be generic:
class DocumentSerializer<T>
implements JsonConverter<DocumentReference<T>, DocumentReference<T>> {
const DocumentSerializer();
#override
DocumentReference<T> fromJson(DocumentReference<T> docRef) => docRef;
#override
DocumentReference<T> toJson(DocumentReference<T> docRef) => docRef;
}
And this is the usage of the annotation:
#JsonSerializable(explicitToJson: true)
class Recipe {
#DocumentSerializer<Recipe>()
final DocumentReference<Recipe> id;
#DocumentSerializer<User>()
final DocumentReference<User> authorId;
final String title;
final String description;
final String imageUrl;
final List<DocumentReference<User>> likes;
final List<String> ingredients;
final List<String> steps;
.
.
.
}
Unfortunately, this does not work. The build runner fails when it reaches the first usage of the annotation, which is the id field. Is there a way to provide generics to DocumentReferences in JsonConverter which can be serialized properly?
I found a workaround; albeit less elegant than what I'm aiming for. Turns out separate JsonConverters need to be created for each DocumentReference type.
For example, if I have an id field of type DocumentReference<Recipe> for the Recipe class , I would need to create the following JSON converter...
class RecipeSerializer
implements
JsonConverter<DocumentReference<Recipe>, DocumentReference<Recipe>> {
const RecipeSerializer();
#override
DocumentReference<Recipe> fromJson(DocumentReference<Recipe> json) => json;
#override
DocumentReference<Recipe> toJson(DocumentReference<Recipe> object) => object;
}
...and use it as such:
#JsonSerializable(explicitToJson: true)
class Recipe {
#RecipeSerializer()
final DocumentReference<Recipe> id;
#UserSerializer() // <- same goes for other types
final DocumentReference<User> authorId;
final String title;
final String description;
final String imageUrl;
final List<DocumentReference<User>> likes;
final List<String> ingredients;
final List<String> steps;
.
.
.
}
A bit more verbose, but I'll take it unless someone comes up with a more efficient answer.

how to use freezed on a class with custome function that inherits from a non-sealed class in dart?

I have just started learning freezed. I have a GameBase class below:
import 'package:json_annotation/json_annotation.dart';
part 'game_base.g.dart';
#JsonSerializable()
class GameBase {
final int id;
final String facilityName;
final ActivityType activityType;
final Level level;
final DateTime startTime;
final DateTime endTime;
final int participantsNumber;
final String admin;
const GameBase(
{required this.id,
required this.level,
required this.activityType,
required this.admin,
required this.startTime,
required this.facilityName,
required this.endTime,
required this.participantsNumber});
factory GameBase.fromJson(Map<String, dynamic> json) =>
_$GameBaseFromJson(json);
}
Now i have another class called Game, which extends from GameBase. I'm trying to use freezed on this class. I also have a getter in this class. Game class is shown bellow:
part 'game.freezed.dart';
part 'game.g.dart';
#freezed
class Game extends GameBase with _$Game {
Game._();
factory Game({
required List<UserBase> participants,
required String? gameDescription,
required String? activityGroundsName,
required DateTime day,
required double lat,
required double lng,
required int id,
required Level level,
required ActivityType activityType,
required String admin,
required DateTime startTime,
required String facilityName,
required DateTime endTime,
required int participantsNumber,
}) = _Game;
factory Game.fromJson(Map<String, dynamic> json) => _$GameFromJson(json);
get facilityActivityText {
if (activityGroundsName == null) {
return facilityName;
} else {
return facilityName + " - " + activityGroundsName!;
}
}
}
since I have a getter in this class, I must have a private custructor, as mentioned in freezed documentation. However, by doing so I get an error since I extend from GameBase and must call its costructor with its fields.
*Note: I know I can move one field up to GameBase and then have my getter over there without any issue, but since I've just started working with freezed I want to understand it better and find out if there's any way to handle this?
I think your problem's same as this thread. Hope this thread will answer ur questions.
Flutter/Dart: Subclass a freezed data class

Is there a way to get a string representation of a variable in a dart class?

In my Flutter app, I have a class named Task as follows:
class Task {
final String id;
final String title;
final String description;
final DateTime date;
bool isDone;
Task({
required this.id,
required this.title,
this.description = "",
required this.date,
this.isDone = false,
});
}
Now I want to map this class to a database table, means for that I need to map every member of the class with a string to create a table. Like this:
"CREATE TABLE tasks (id TEXT PRIMARY KEY, title TEXT, description TEXT)"
Is there a way in Dart to get a String representation of class members, so to avoid declaring additional static const members just for the names of these members, and also to avoid hardcoding these names every place I need them. Thanks.
You need some reflection, you can get that from the official mirrors library: https://api.dart.dev/stable/2.16.1/dart-mirrors/dart-mirrors-library.html

Is required register a list of Objects in Hive?

This is my Hive model and I already generate the adapter:
#HiveType(typeId: 7)
class GoalModel {
#HiveField(0)
bool progessNotificaitons;
#HiveField(1)
List<DayModel> daysToWork;
#HiveField(2)
int amountGoal;
#HiveField(3)
DateTime initialDate;
GoalModel({
this.amountGoal,
this.daysToWork,
this.initialDate,
this.progessNotificaitons,
});
}
class DayModel {
String label;
int index;
bool gonnaWork;
DayModel({
this.gonnaWork,
this.index,
this.label,
});
}
The issue is that does not allow me save the daysToWork which is a list of the class DayModel which does not have an adapter. the question is: is required generate an adapter or any special config to save a list of a type of object?
Thanks in advance.
The response is YES, is required generate an register a new adapter even if you just are going to issue the object into a list of another object.