Issue
Recently updated from 1.0.0 to 1.1.1 and my relation code quit working, I’m unsure what I missed exactly but everything up until the querying of the item seems to work correctly.
This is what I have, and I could really use some help figuring out what I missed
Store Creation:
void initializeUserInventory() async {
await getApplicationDocumentsDirectory().then((dir) {
try {
_quickSaveStore =
Store(getObjectBoxModel(), directory: dir.path + '/quickSaveItems');
_quickActionStore = Store(getObjectBoxModel(),
directory: dir.path + '/quickSaveActions');
_categorizedSaveStore = Store(getObjectBoxModel(),
directory: dir.path + '/categorizedSaveItems');
_itemCategoryStore = Store(getObjectBoxModel(),
directory: dir.path + '/categorizedSaveCategories');
_itemTagsStore = Store(getObjectBoxModel(),
directory: dir.path + '/categorizedSaveTags');
} catch (e) {
print(e.toString());
}
}).whenComplete(() {
// Must initialize everything else after completion of store initialization!
_userQuickSaveBox = Box<InitialItem>(_quickSaveStore!);
_quickActionSaveBox = Box<QuickSaveAction>(_quickActionStore!);
_categorizedSaveBox = Box<InitialItem>(_categorizedSaveStore!);
_itemCategoryBox = Box<ItemCategory>(_itemCategoryStore!);
_itemTagsBox = Box<ItemTag>(_itemTagsStore!);
});
}
Here are the entity files:
InitialItem:
part 'initial_item.g.dart';
@JsonSerializable(explicitToJson: true)
@Entity()
class InitialItem {
String? itemName;
String? inc;
DateTime cacheTime;
DateTime? saveTime;
@Id(assignable: true)
int id;
//#region Category
//
// Functions that are utilized for Saving the item by Category
//
/// Holds the count of how many items the vehicle/WO needs
int? quantity;
/// Any comments the user has added to the item
String? userComment;
/// Category that the item belongs too
final itemCategory = ToOne<ItemCategory>();
/// Allows adding a tag to the saved item
final tags = ToMany<ItemTag>();
//#endregion
InitialItem(
{this.id = 0,
this.itemName,
this.inc,
this.quantity = 1,
DateTime? cacheTime,
DateTime? saveTime,
this.userComment = '',})
: cacheTime = cacheTime ?? DateTime.now(),
saveTime = cacheTime ?? DateTime.now();
}
ItemCategory:
part 'item_category.g.dart';
@JsonSerializable(explicitToJson: true)
@Entity()
class ItemCategory {
int id;
String? categoryUid;
String? userUid;
String? categoryName;
String? categoryComment;
@Backlink()
final items = ToMany<InitialItem>();
ItemCategory(
{this.id = 0,
this.userUid,
this.categoryName,
this.categoryUid,
this.categoryComment});
}
ItemTag:
part 'item_tag.g.dart';
@JsonSerializable(explicitToJson: true)
@Entity()
class ItemTag {
int id;
String? name;
/// Only used for FilterChip display, not saved in any database
@Transient()
bool isSelected;
String? uid;
ItemTag({this.id = 0, this.name, this.isSelected = false, this.uid});
}
The Tags and the Categories are already created by the user and saved in their boxes. An item is passed into the view, the user can add tag(s) to the item, and can select a category to save the item under.
/// Attaches the tags that the user selected to the item for saving
void attachTagsToItem() {
// Clear all previous tags before adding the selected tags
savingItem?.tags.clear();
savingItem?.tags.addAll(enabledTagList);
}
The item then has the selected category written to it’s toOne target and it is saved — savingItem correctly has everything in it right here
bool saveCategorizedItem() {
if (selectedCategory != null) {
// Set the item category
savingItem!.itemCategory.target = selectedCategory;
_userInventoryService.addCategorizedItemToLocal(savingItem!);
return true;
} else {
return false;
}
}
Where it’s saved — at this point, everything checks out. I can debug and see the tags and information in their variable, and I can see the Category and it’s information in itemCategory.
void addCategorizedItemToLocal(InitialItem saveItem) {
_categorizedSaveBox.put(saveItem);
print('Item saved to categorized database');
}
Later on, I query every item that is saved in order to group them into lists. And at this point It only returns the InitialItem, and it doesn’t pull the relation data with it. Both toOne and toMany’s targets are null.
/// Returns all the of Items that have been categorized and saved
List<InitialItem> getAllCategorizedItems() => _categorizedSaveBox.getAll();
------------------------------------------------------------------------------------------
Calling the query in the View Provider's class
void getCategorizedItems() {
_categorizedSaveList = _userInventoryService.getAllCategorizedItems();
notify(ViewState.Idle);
}
I then attempt to build the list using the returned query. element.itemCategory.target returns null, and the same goes for the tags. As I stated, this all was previously working in version 1.0.0, and it fails after upgrading, with no other changes made. Is there something wrong with the query in general? I can view the relations in the debug window so I’m assuming that is set correctly, it just doesn’t appear to be pulling the objects with the original query.
Can anyone shed some light on what I’m doing wrong?
Widget categorizedList(BuildContext context) {
final saveProvider =
Provider.of<UserInventoryProvider>(context, listen: true);
return GroupedListView<dynamic, String>(
physics: const BouncingScrollPhysics(),
elements: saveProvider.categorizedSaveList,
groupBy: (element) => element.itemCategory.target!.categoryName,
groupComparator: (d1, d2) => d2.compareTo(d1),
groupSeparatorBuilder: (String value) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text(value,
textAlign: TextAlign.center,
style: TextStyles.kTextStyleWhiteLarge),
),
indexedItemBuilder: (c, element, index) {
return Container();
},
);
}
Solution
After all the talks in the comments, I’ve finally noticed you initialize multiple stores. Effectively, you’re working with multiple standalone databases, therefore the relations couldn’t work as expected. Your initializeUserInventory()
should look something like:
void initializeUserInventory() async {
_store = await openStore(); // new shorthand in v1.1, uses getApplicationDocumentsDirectory()
_userQuickSaveBox = _store.box();
_quickActionSaveBox = _store.box();
_categorizedSaveBox = _store.box();
_itemCategoryBox = _store.box();
_itemTagsBox = _store.box();
}
Answered By – vaind
Answer Checked By – Timothy Miller (FlutterFixes Admin)