How to save this nested class in Isar DB Flutter

1.3k Views Asked by At

I have the following 4 classes. In this, only the ProductGroup is saved, ProductVariant, ProductSize and ProductColor are not stored. Please help me with this.

product_group.dart

@Collection()
class ProductGroup {
  late Id id;

  @Index(caseSensitive: false)
  late String productGroupName;

  final productVariants = IsarLinks<ProductVariant>();

  ProductGroup();

  ProductGroup.fromJson(Map<String, dynamic> json) {
    id = json['Id'];
    productGroupName = json['PG'];
    if (json['Ps'] != null) {
      json['Ps'].forEach((variant) {
        productVariants.add(ProductVariant.fromJson(variant));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['Id'] = id;
    data['PG'] = productGroupName;
    data['Ps'] = productVariants.map((variant) => variant.toJson()).toList();
    return data;
  }
}

product_variant.dart

@Collection()
class ProductVariant {
  late Id id;
  late String variantName;
  final productSizes = IsarLinks<ProductSize>();

  ProductVariant();

  ProductVariant.fromJson(Map<String, dynamic> json) {
    id = json['Id'];
    variantName = json['St'];
    if (json['Ss'] != null) {
      json['Ss'].forEach((v) {
        productSizes.add(ProductSize.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['Id'] = id;
    data['St'] = variantName;
    data['Ss'] = productSizes.map((v) => v.toJson()).toList();
    return data;
  }
}

product_size.dart

@Collection()
class ProductSize {
  late Id id;
  late String size;
  final productColors = IsarLinks<ProductColor>();

  ProductSize();

  ProductSize.fromJson(Map<String, dynamic> json) {
    id = json['Id'];
    size = json['S'];
    if (json['Cs'] != null) {
      json['Cs'].forEach((v) {
        productColors.add(ProductColor.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['Id'] = id;
    data['S'] = size;
    data['Cs'] = productColors.map((color) => color.toJson()).toList();
    return data;
  }
}

product_color.dart

@Collection()
class ProductColor {
  late Id id;
  late String colorName;
  late String colorHexCode;

  ProductColor();

  ProductColor.fromJson(Map<String, dynamic> json) {
    id = json['Id'];
    colorName = json['C'];
    colorHexCode = json['CC'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['Id'] = id;
    data['C'] = colorName;
    data['CC'] = colorHexCode;
    return data;
  }
}

I am parsing the json and saving it in Isar

convertJsonToIsar() async {
    try {
      // For testing purposes, loading Json from assets, in Prod, Json will be fetched from server
      final String response = await rootBundle.loadString('assets/pr_dump.json');
      final data = await json.decode(response);


      List<ProductGroup> productGroupList = [];
      data.forEach((item) {
        productGroupList.add(ProductGroup.fromJson(item));
      });

      Isar _isar = getIsar();

      _isar.writeTxnSync(() {
         _isar.productGroups.putAllSync(productGroupList, saveLinks: true);
      });

    } catch (e) {
      // Handle Error
      print('Caught Error');
      print(e.toString());
      return 0;
    }
  }

Only the ProductGroup is stored, ProductVariant, ProductSize and ProductColor are not stored. Please help me with this.

1

There are 1 best solutions below

0
On

As stated in the Isar docs: "Links are lazy, so you need to tell the IsarLink to load or save the value explicitly. You can do this by calling linkProperty.load() and linkProperty.save()."

So every time you want to save a property that is an IsarLink, you need to call save() function.

So using your example, imagine that you have a variable called ProductGroup productGroup and an Isar instance called isar. To save it on Isar, you need to go:

await isar.writeTxn(() async {
  await isar.productGroups.put(productGroup);
  await productGroup.productVariant.save();

// ... and so on
    });