isar / hive

Lightweight and blazing fast key-value database written in pure Dart.
Apache License 2.0
4.1k stars 407 forks source link

Save decode json to hive box #672

Open Diy2210 opened 3 years ago

Diy2210 commented 3 years ago

Hi, I'm new in dart. I want save decode json in box => JSON like this:

{
    "data": [
        {
            "id": 1,
            "parent_id": 0,
            "title": "Baby",
            "price": 10,
            "badges_count": 1873
        },
        {
            "id": 2,
            "parent_id": 0,
            "title": "Health and Beauty",
            "price": 10,
            "badges_count": 1809
        },
        {
            "id": 3,
            "parent_id": 0,
            "title": "Clothing",
            "price": 10,
           ]
}

I create model and generate adapter, init hive.box. My model:

@HiveType(typeId: HiveTypes.categories)
class Categories {
  @HiveField(0)
  int id;
  @HiveField(1)
  int parentID;
  @HiveField(3)
  String title;
  @HiveField(4)
  int price;
  @HiveField(5)
  int badgeCount;

  Categories({
    this.id = 0,
    this.parentID = 0,
    this.title = '',
    this.price = 0,
    this.badgeCount = 0
  });
}

And class helper for save it:

class CategoriesDataHelper {
  Box<Categories> _categories;

  //Save categories to Hive box
  void saveCategories(Categories categories) {
    _categories = Hive.box<Categories>('categories_db');
    _categories.put('categories', categories);
  }

  //Get categories from Hive box
  Categories getCategories() {
    _categories = Hive.box<Categories>('categories_db');
    return _categories.get('categories');
  }

  Future<void> cacheCategories(dynamic categoriesData) async {
    Categories categories;
    categories = Categories(
      id: categoriesData['id'],
      parentID: categoriesData['parent_id'],
      title: categoriesData['title'],
      price: categoriesData['price'],
      badgeCount: categoriesData['badges_count'],
    );
    saveCategories(categories);
  }

  Future<void> clear() async {
    await Hive.box<Categories>('categories_db').clear();
  }
}

This method for save:

/.../
var jsonResponse = convert.jsonDecode(resp.body);
      var categories = jsonResponse['data'].toList();
      CategoriesDataHelper().cacheCategories(categories);
baumths commented 3 years ago

Hey! The only thing I see might be the issue is with the method saveCategories.

You're using box.put('categories', category), the put method overrides the key 'categories', to add multiple entries to the box you should either use different keys (i.e. box.put(category.id, category)) or use the box.add(category) method that gives an auto incremented key to each entry.

Edit: and in the cacheCategories method since you are passing it a list, you should iterate through it and add each list entry to the box.

Pro tip: avoid using the dynamic type when possible, it creates too much errors.

Do something like

Future<void> cacheCategories(List<Map> categoriesData) {
  categoriesData.forEach((Map category) {
     var categories ​=​ ​Categories​(
        id​:​ category[​'id'​] as int,
        parentID​:​ category[​'parent_id'​] as int,
        title​:​ category[​'title'​] as String,
        price​:​ category[​'price'​] as int, 
        badgeCount​:​ category[​'badges_count'​] as int,
    );
    saveCategories(categories);
  });
}

And in the jsonDecode part:

​var​ jsonResponse ​=​ (convert.​jsonDecode​(resp.body) as Map)?.cast<String, dynamic>();
      ​var​ categories ​=​ (jsonResponse[​'data'] as List).cast<Map>();
      ​CategoriesDataHelper​().​cacheCategories​(categories);

You might have to tweak a bit the code to work, but working with json is kind of complicated because of the type casts in dart.