Gaurav Kumar
Gaurav Kumar

Reputation: 1231

How to write custom class object in hive object?

While using hive in flutter I used my custom class object Profile profile in hive object.

So, initially, I set the custom class object(Profile profile) as null while adding in Hive box.

Following is my Hive class:

import 'dart:convert';
import 'package:hive/hive.dart';
import 'package:lpa_exam/src/model/listofexams.dart';
import 'package:lpa_exam/src/model/profile.dart';
part 'hiveprofile.g.dart';

@HiveType()
class PersonModel extends HiveObject{
  @HiveField(0)
  String language;

  @HiveField(1)
  String examName;

  @HiveField(2)
  int examId;

  @HiveField(3)
  Profile profile;

  @HiveField(4)
  ListExam listexam;

  @override
  String toString() {
    return jsonEncode({
      'language': this.language,
      'examName': this.examName,
      'examId': this.examId,
      'profile': this.profile,
      'listexam': this.listexam
    });
  }

  PersonModel(
      this.language, this.examName, this.examId, this.profile, this.listexam);
}

Profile class for reference:

class Profile {
  String name='';
  String lang='';
  String emailId='';
  String mobileNumber='';
  String state='';
  String city='';
  String district='';
  String pinCode='';
  String profilePic='';
  Profile(
      this.name,
      this.lang,
      this.emailId,
      this.mobileNumber,
      this.district,
      this.state,
      this.city,
      this.pinCode,this.profilePic);

  Profile.fromJson(Map<String, dynamic> json) {
    // print('fromjson:$json');
    if (json != null) {
      name = json['name'];
      lang = json['language'];
      emailId = json['emailId'];
      mobileNumber = json['mobileNumber'];
      district = json['district'];
      state = json['state'];
      city = json['city'];
      pinCode = json['pinCode'];
      profilePic=json['profilePic'];
    } else {
      print('in else profile from json');
      // name = '';
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['language'] = this.lang;
    data['emailId'] = this.emailId;
    data['mobileNumber'] = this.mobileNumber;
    data['district'] = this.district;
    data['state'] = this.state;
    data['city'] = this.city;
    data['pinCode'] = this.pinCode;
    data['profilePic']=this.profilePic;
    return data;
  }
}

An error occurred when I tried to add the added object like this

item.add(PersonModel(label, null, null, Profile(), ListExam())); // label='English'

Following is the error which occurred:

[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: HiveError: Cannot write, unknown type: Profile. Did you forget to register an adapter?

Now, can somebody point out what am I doing wrong here?

Upvotes: 13

Views: 14729

Answers (4)

Huzaifa Khan
Huzaifa Khan

Reputation: 179

You can get a rough idea from this code:

Khata Model:

part 'khata_model.g.dart';

@HiveType(typeId: 0)
class KhataModel extends HiveObject {
  // Hive Fields:

  @HiveField(0)
  DateTime? date;

  @HiveField(1)
  double? literPrice;

  @HiveField(2)
  List<EntryModel> entryModel;

  KhataModel({this.date, this.literPrice, required this.entryModel});
}

Entry Model:

part 'entry_model.g.dart';

@HiveType(typeId: 1)
class EntryModel extends HiveObject {
  // Fields:

  @HiveField(0)
  DateTime? date;

  @HiveField(1)
  double? quantity;

  @HiveField(2)
  double? entryPrice;

  EntryModel({this.date, this.quantity, this.entryPrice});
}

Add Entries Button:

    child: ElevatedButton(
            onPressed: () async {
              final box = Boxes.getKhataData();

              final existingKhataModel = box.get(0);

              if (existingKhataModel != null) {
                final entryModel = EntryModel(
                    date: newDate,
                    quantity: dropDownValue,
                    entryPrice:
                        (dropDownValue * existingKhataModel.literPrice!));

                existingKhataModel.entryModel.add(entryModel);

                existingKhataModel.save();

                Navigator.pop(context);
              } else {
                print('KhataModel not found in the box');
              }
            },
            child: const Text("Add Entry"),
          ),

Note: "newDate" is any selected date that we get using DatePicker. "Quantity" is getting from a dropdownmenu Button.

Upvotes: 1

Arunjith R S
Arunjith R S

Reputation: 862

Hope it helped!

@HiveType(typeId: 0)
class TradingJournalLocal extends HiveObject {
  @HiveField(0)
  late String orderType;

  @HiveField(1)
  late String title; 

  @HiveField(2)
  late List<Emotion> emotions; 
} 

@HiveType(typeId: 1)
class Emotion extends HiveObject {
  @HiveField(0)
  late int id;

  @HiveField(1)
  late String emoji; 

  Emotion({
    required this.id,
    required this.emoji,
  });

  factory Emotion.fromJson(Map<String, dynamic> json) => Emotion(
        id: json['id'],
        emoji: json['emoji'],
      ); 
}

Upvotes: -1

Hive plugin supports primitives, lists and maps by default. To use it for your own Dart object you need to generate a TypeAdapter.

You need to create a TypeAdapter for each object that you have. So you need to apply same things for Profile class that you did for PersonModel

part 'profile.g.dart';

@HiveType()
class Profile {
  @HiveField(0)
  String name;
  @HiveField(1)
  String lang;
  @HiveField(2)
  String emailId;
  @HiveField(3)
  String mobileNumber;
  @HiveField(4)
  String state;
  @HiveField(5)
  String city;
  @HiveField(6)
  String district;
  @HiveField(7)
  String pinCode;
  @HiveField(8)
  String profilePic;

  Profile(
      this.name,
      this.lang,
      this.emailId,
      this.mobileNumber,
      this.district,
      this.state,
      this.city,
      this.pinCode,this.profilePic);      


  Profile.fromJson(Map<String, dynamic> json) {
    // print('fromjson:$json');
    if (json != null) {
      name = json['name'];
      lang = json['language'];
      emailId = json['emailId'];
      mobileNumber = json['mobileNumber'];
      district = json['district'];
      state = json['state'];
      city = json['city'];
      pinCode = json['pinCode'];
      profilePic=json['profilePic'];
    } else {
      print('in else profile from json');
      // name = '';
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['language'] = this.lang;
    data['emailId'] = this.emailId;
    data['mobileNumber'] = this.mobileNumber;
    data['district'] = this.district;
    data['state'] = this.state;
    data['city'] = this.city;
    data['pinCode'] = this.pinCode;
    data['profilePic']=this.profilePic;
    return data;
 }

}

If you are using latest hive version you will also need to give a type id for your HiveType like

@HiveType(typeId: 0)

And I see that you have another custom class called ListExam. You will also need to do the same things for that class

Upvotes: 9

chunhunghan
chunhunghan

Reputation: 54377

You can copy paste run full code below main.dart and main.g.dart
For demo, I remark listexam
You need to registerAdapter(ProfileAdapter()) and
create class ProfileAdapter extends TypeAdapter<Profile> see full code below
code snippet

Hive
    ..init(dir.path)
    ..registerAdapter(PersonModelAdapter())
    ..registerAdapter(ProfileAdapter());


  var box = await Hive.openBox('testBox');

  var personModel = PersonModel(
      language: "en",
      examName: "abc",
      examId: 123,
      profile: Profile(name: "test", emailId: "[email protected]"));

  await box.put('test', personModel);

  print(box.get('test'));

output

I/flutter (10795): {"language":"en","examName":"abc","examId":123,"profile":{"name":"test","language":null,"emailId":"[email protected]","mobileNumber":null,"district":null,"state":null,"city":null,"pinCode":null,"profilePic":null}}

main.dart

import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';

part 'main.g.dart';

@HiveType(typeId: 1)
class PersonModel extends HiveObject {
  @HiveField(0)
  String language;

  @HiveField(1)
  String examName;

  @HiveField(2)
  int examId;

  @HiveField(3)
  Profile profile;

  /*@HiveField(4)
  ListExam listexam;*/

  @override
  String toString() {
    return jsonEncode({
      'language': this.language,
      'examName': this.examName,
      'examId': this.examId,
      'profile': this.profile,
      //'listexam': this.listexam
    });
  }

  PersonModel(
      {this.language,
      this.examName,
      this.examId,
      this.profile} /*, this.listexam*/);
}

@HiveType(typeId: 2)
class Profile extends HiveObject {
  String name = '';
  String lang = '';
  String emailId = '';
  String mobileNumber = '';
  String state = '';
  String city = '';
  String district = '';
  String pinCode = '';
  String profilePic = '';

  Profile(
      {this.name,
      this.lang,
      this.emailId,
      this.mobileNumber,
      this.district,
      this.state,
      this.city,
      this.pinCode,
      this.profilePic});

  Profile.fromJson(Map<String, dynamic> json) {
    // print('fromjson:$json');
    if (json != null) {
      name = json['name'];
      lang = json['language'];
      emailId = json['emailId'];
      mobileNumber = json['mobileNumber'];
      district = json['district'];
      state = json['state'];
      city = json['city'];
      pinCode = json['pinCode'];
      profilePic = json['profilePic'];
    } else {
      print('in else profile from json');
      // name = '';
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['language'] = this.lang;
    data['emailId'] = this.emailId;
    data['mobileNumber'] = this.mobileNumber;
    data['district'] = this.district;
    data['state'] = this.state;
    data['city'] = this.city;
    data['pinCode'] = this.pinCode;
    data['profilePic'] = this.profilePic;
    return data;
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  var dir = await getApplicationDocumentsDirectory();
  Hive
    ..init(dir.path)
    ..registerAdapter(PersonModelAdapter())
    ..registerAdapter(ProfileAdapter());

  var box = await Hive.openBox('testBox');

  var personModel = PersonModel(
      language: "en",
      examName: "abc",
      examId: 123,
      profile: Profile(name: "test", emailId: "[email protected]"));

  await box.put('test', personModel);

  print(box.get('test'));
}

main.g.dart

part of 'main.dart';

// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************

class PersonModelAdapter extends TypeAdapter<PersonModel> {
  @override
  final typeId = 1;

  @override
  PersonModel read(BinaryReader reader) {
    var numOfFields = reader.readByte();
    var fields = <int, dynamic>{
      for (var i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return PersonModel()
      ..language = fields[0] as String
      ..examName = fields[1] as String
      ..examId = fields[2] as int
      ..profile = fields[3] as Profile;
  }

  @override
  void write(BinaryWriter writer, PersonModel obj) {
    writer
      ..writeByte(3)
      ..writeByte(0)
      ..write(obj.language)
      ..writeByte(1)
      ..write(obj.examName)
      ..writeByte(2)
      ..write(obj.examId)
      ..writeByte(3)
      ..write(obj.profile);
  }
}

class ProfileAdapter extends TypeAdapter<Profile> {
  @override
  final typeId = 2;

  @override
  Profile read(BinaryReader reader) {
    var numOfFields = reader.readByte();
    var fields = <int, dynamic>{
      for (var i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return Profile()
      ..name = fields[0] as String
      ..lang = fields[1] as String
      ..emailId = fields[2] as String
      ..mobileNumber = fields[3] as String
      ..district = fields[4] as String
      ..state = fields[5] as String
      ..city = fields[6] as String
      ..pinCode = fields[7] as String
      ..profilePic = fields[8] as String;
  }

  @override
  void write(BinaryWriter writer, Profile obj) {
    writer
      ..writeByte(3)
      ..writeByte(0)
      ..write(obj.name)
      ..writeByte(1)
      ..write(obj.lang)
      ..writeByte(2)
      ..write(obj.emailId)
      ..writeByte(3)
      ..write(obj.mobileNumber)
      ..writeByte(4)
      ..write(obj.district)
      ..writeByte(5)
      ..write(obj.state)
      ..writeByte(6)
      ..write(obj.city)
      ..writeByte(7)
      ..write(obj.pinCode)
      ..writeByte(8)
      ..write(obj.profilePic);
  }
}

Upvotes: 4

Related Questions