updateDoc method

  1. @protected
Future<TurboResponse<DTO>> updateDoc({
  1. Transaction? transaction,
  2. required String id,
  3. required UpdateDocDef<DTO, MODEL> doc,
  4. TWriteableId remoteUpdateRequestBuilder(
    1. DTO doc
    )?,
  5. bool doNotifyListeners = true,
})

Updates a document both locally and in Firestore.

Performs an optimistic update by updating the local state first, then syncing with Firestore. If the remote update fails, the local state remains updated.

Sends only fields that changed since the last known local state. The pre-mutation DTO is captured before the local state is updated and forwarded to the API as previousWriteable so the API can compute a minimal diff payload (and skip the write entirely on a no-op).

The document with id must already exist in local state before calling this method.

If remoteUpdateRequestBuilder is provided, it must be deterministic — it is applied to BOTH the previous DTO and the new DTO so the diff inputs share the same shape.

Parameters:

  • transaction - Optional transaction for atomic operations
  • id - The ID of the document to update
  • doc - The definition of how to update the document
  • remoteUpdateRequestBuilder - Optional builder to modify the document before updating
  • doNotifyListeners - Whether to notify listeners of the change

Returns a TurboResponse with the updated document reference

Implementation

@protected
Future<TurboResponse<DTO>> updateDoc({
  Transaction? transaction,
  required String id,
  required UpdateDocDef<DTO, MODEL> doc,
  TWriteableId Function(DTO doc)? remoteUpdateRequestBuilder,
  bool doNotifyListeners = true,
}) async {
  try {
    log.debug('Updating doc with id: $id');
    final DTO? previousDto = tryFindById(id)?.dto;
    final pDoc = updateLocalDoc(
      id: id,
      doc: doc,
      doNotifyListeners: doNotifyListeners,
    );
    final TWriteableId newWriteable =
        remoteUpdateRequestBuilder?.call(pDoc) ?? pDoc as TWriteableId;
    final TWriteableId? previousForRemote = previousDto == null
        ? null
        : (remoteUpdateRequestBuilder != null
              ? remoteUpdateRequestBuilder(previousDto)
              : previousDto as TWriteableId);
    final future = api.updateDoc(
      writeable: newWriteable,
      previousWriteable: previousForRemote,
      id: id,
      transaction: transaction,
    );
    final turboResponse = await future;
    if (transaction != null) {
      turboResponse.throwWhenFail();
    }
    return turboResponse.mapSuccess((_) => pDoc);
  } catch (error, stackTrace) {
    if (transaction != null) rethrow;
    log.error(
      '$error caught while updating doc',
      error: error,
      stackTrace: stackTrace,
    );
    return TurboResponse.fail(error: error);
  }
}