skip to Main Content

I have a Hive box to save a Map<String, dynamic> using toJson(). But when I retrieve it, the result are a Map<dynamic, dynamic>, I’ve tried converting it using jsonDecode(), but not working. I also have tried converting it to String first then wrapping it up with jsonEncode() then jsonDecode(), still not working.

PS: Datatype other than a Map does work without problem

final HiveHelper hh = HiveHelper();
final box = Hive.openBox('boxip');
...
...
Future<void> saveDataIp(Map<String, dynamic> ip) async {
    await hh.saveToBox(box, 'ip', ip);
}
...
Map<String, dynamic> getDataIp() {
    Map<String, dynamic> map = {};
    // ip resulting a _Map<dynamic, dynamic>
    final ip = hh.getFrombox(box, 'ip');
    if (ip != null) {
      // with only using jsonDecode() gives error type "'_Map<dynamic, dynamic>' is not a subtype of type 'String'"
      // below gives error "Converting object to an encodable object failed: Instance of 'DateTime'"
      map = Map<String, dynamic>.from(jsonDecode(jsonEncode(ip)));
    }
    return map;
  }
...
...
...
final data = Data(id: 1, name: "item", date: "2023-07-17T10:45:40.070Z");
await saveDataIp(data.toJson());
final dataBox = getDataIp();

2

Answers


  1. First, here are 2 types to get a cleaner code and get less lost in your code:

    • type your variables
    • use an analysis_options.yaml with linter rules

    I’m not sure to understand what is your problem.

    If I summarise:

    • you create an obejct with type Data
    • you transform it to json => type Map<String, dynamic>
    • you save it into a hiveBox
    • you get it back with getFrombox() under Map<String, dynamic> type

    then what do you need to do? You can add a fromMap() method in your Data class to parse your box result back into Data type.

    Also why don’t you use directly box.save() and box.get()?

    Login or Signup to reply.
  2. data.dart:

    import 'dart:convert';
    
    class Data {
      final int id;
      final String name;
      final DateTime date;
    
      Data({required this.id, required this.name, required this.date});
    
      Map<String, dynamic> toMap() {
        return <String, dynamic>{
          'id': id,
          'name': name,
          'date': date.millisecondsSinceEpoch,
        };
      }
    
      factory Data.fromMap(Map<String, dynamic> map) {
        return Data(
          id: map['id'] as int,
          name: map['name'] as String,
          date: DateTime.fromMillisecondsSinceEpoch(map['date'] as int),
        );
      }
    
      String toJson() => json.encode(toMap());
    
      factory Data.fromJson(String source) =>
          Data.fromMap(json.decode(source) as Map<String, dynamic>);
    }

    Then:

    Future<void> saveDataIp(Data data) async {
        await hh.saveToBox(box, 'ip', data.toMap());
    }
    Data getDataIp() {
        Map<String, dynamic> map = {};
        // ip resulting a _Map<dynamic, dynamic>
        final Map<String, dynamic>? dataMap = hh.getFrombox(box, 'ip');
        if (ip == null) {
          throw Exception('No ip found in the hiveBox');
        }
        return Data.fromMap(dataMap);
      }

    And:

    final Data dataToSave = Data(id: 1, name: "item", date: DateTime.parse("2023-07-17T10:45:40.070Z");
    
    await saveDataIp(data);
    
    final Data dataRead = getDataIp();

    let me know if it answers your need

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search