0

I guess the best (only?) way is to create a separate box for the nested structure and then to create a relation from parent (ONE) to children (MANY).

However, my issue is how to implement a .toObjectBox() method to convert my domain data model into the ObjectBox data model. Is there anything alike Either from the dartz package (returns either a left or a right side object), which transports 2 objects simultaneously?

So with the ObjectBox Entities

@Entity()
class Customer {
  int id;
  @Backlink('customer')
  final orders = ToMany<Order>();
}

@Entity()
class Order {
  int id;
  final customer = ToOne<Customer>();
}

I would store the parent (customer) with the nested data objected (order) in the 2 related boxes

Customer customer = domainData.toObjectBox; // but how to get the order out?
customer.orders.add(Order('Order 1'));  // shouldn't this be Order(1)?
final customerId = store.box<Customer>().put(customer);

This is how I typically implement the toObjectBox method. By here, you see that this does not work out because I would have to split parent and nested child apart. While I guess I could achieve this with some spaghetti, I wonder if there is a smart way of doing so since I guess this should be a common pattern (though I haven't found any Q&A on it).

@Entity()
Customer {
  int id;
  List<Order> orders;
  Customer({required this.id, required this.orders});
  
  CustomerObox toObjectBox() {
    return CustomerObox(
      id: id,
//      orders: orders.map((x) => x.toObjectBox()).toList()
    );
}

=== UPDATE =====================================

I have meanwhile tried to create a return structure myself, and now I am in the process to get this working.

class Pair<T1, T2> {
  final T1 parent;
  final T2 child;
  Pair({required this.parent, required this.child});
}

@Entity()
class Customer {
  int id;
  List<Order> orders;
  Customer({required this.id, required this.orders});
      
  static Pair<CustomerObox, List<OrderObox>> toObjectBox(Customer cust) {
    Pair<CustomerObox, List<OrderObox>>(
        parent: CustomerObox(
                  id: cust.id,
                ),
        child: cust.orders.map((o) => o.toObjectBox()).toList()
    );
  }      
}
w461
  • 2,168
  • 4
  • 14
  • 40
  • Reasons you cannot/don't want to annotate your domain classes with `@Entity()` as described in the first code block? That would yield the best results without any manually written (==fragile) conversions... – vaind Aug 20 '21 at 15:54
  • Just forgot to type it here. Since my real life code would make it harder to follow, I adapted the ObjectBox example - but only within the editor of stackoverflow, not in IDE. I updated the code, so I assume all @Entity() should be present now – w461 Aug 20 '21 at 16:14

1 Answers1

0

So I implemented toObjectBox as shown in the update of my question above.

Inside my local datasource implementation (I use the layers: presentation > business logic (bloc) > domain (models, contracts etc) > repository > datasource) I implemented the following methods

@override
  Future<void> storeCustomer(Customer customer) async {
    // Pair(T1 parent, T2 child) with T2 being List<OrderObox>
    final Pair customerObox = Customer.toObjectBox(customer);
    final CustomerObox customerParent = customerObox.parent;
    final List<OrderObox> customerChildren = customerObox.child;

    for (final child in customerChildren)
      customerParent.records.add(child);
    //  puts both, parent and children:
    final id = _sBox.put(customerParent);
  }
  @override
  Future<List<Customer>> getAllCustomers() async {
    final List<Customer> parents = [];
    final List<CustomerObox> parentsObox = await _sBox.getAll();
    for (final p in parentsObox) {
      final List<CustomerObox> childrenObox = p.records;
      parents.add(SessionJournalDto.fromObjectBox(p));
      for (final c in childrenObox)
        parents.last.records.add(Order.fromObjectBox(c));
    }
    return parents;

  }
w461
  • 2,168
  • 4
  • 14
  • 40