Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write custom class object in hive object?

Tags:

flutter

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?

like image 504
Gaurav Kumar Avatar asked Jan 13 '20 13:01

Gaurav Kumar


2 Answers

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

like image 62
Selim Kundakçıoğlu Avatar answered Oct 01 '22 13:10

Selim Kundakçıoğlu


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);
  }
}
like image 31
chunhunghan Avatar answered Oct 01 '22 13:10

chunhunghan