withSubscriptionEvent method

QuerySnapshot<T> withSubscriptionEvent({
  1. required SubscriptionEvent<T> event,
})

Returns a new QuerySnapshot with the event applied

Takes the existing snapshots QueryPredicate and QuerySortBy conditions into consideration when applying the event

If the event does not result in a change to the QuerySnapshot, the current snapshot is returned

Implementation

QuerySnapshot<T> withSubscriptionEvent({
  required SubscriptionEvent<T> event,
}) {
  SortedList<T>? updatedSortedList;

  final newItem = event.item;
  final matchesPredicate = where == null || where!.evaluate(newItem);
  final currentIndex = _sortedList.indexWhere(
    (item) => item.modelIdentifier == newItem.modelIdentifier,
  );
  final currentItem = currentIndex == -1 ? null : _sortedList[currentIndex];

  switch (event.eventType) {
    case EventType.create:
      // Skip any new item that doesn't match the predicate.
      if (!matchesPredicate) break;
      if (currentItem == null) {
        // Add the item to the list. This is a new item and matches the
        // predicate, it should be added.
        updatedSortedList = _sortedList.copy()..addSorted(newItem);
      } else if (currentItem != newItem) {
        // Update the item in the list. This is a "new" item, but it already
        // exists in the list with a different value. This is the result of
        // the item being created on this device and App Sync returning an
        // updated item during the create mutation. This can happen when using
        // custom resolvers.
        updatedSortedList = _sortedList.copy()
          ..updateAtSorted(
            currentIndex,
            newItem,
          );
      }
    case EventType.update:
      if (currentItem == null && matchesPredicate) {
        // Add the item to the list. This is an existing item that matches the
        // predicate but is not yet in the list.
        updatedSortedList = _sortedList.copy()..addSorted(newItem);
      } else if (currentItem != newItem && matchesPredicate) {
        // Update the item in the list. This item exists in the list but the
        // value of the item has changed.
        updatedSortedList = _sortedList.copy()
          ..updateAtSorted(
            currentIndex,
            newItem,
          );
      } else if (currentItem != null && !matchesPredicate) {
        // Remove the item from the list. The item exist in the list but no
        // longer matches the predicate.
        updatedSortedList = _sortedList.copy()..removeAt(currentIndex);
      }
    case EventType.delete:
      if (currentItem != null) {
        // Remove the item from the list. The item exists in the list but was
        // just deleted.
        updatedSortedList = _sortedList.copy()..removeAt(currentIndex);
      }
  }
  if (updatedSortedList != null) {
    return QuerySnapshot._(
      sortedList: updatedSortedList,
      isSynced: isSynced,
      where: where,
      sortBy: sortBy,
    );
  }
  return this;
}