function adjustPayloadForArray()

in src/components/Firestore/DocumentPreview/api.tsx [65:98]


function adjustPayloadForArray(
  doc: FirestoreMap,
  fieldPath: string[],
  value: FirestoreAny | firebase.firestore.FieldValue
): [firebase.firestore.FieldPath, FirestoreAny] {
  let cur: FirestoreAny | undefined = doc;
  let parentPath: string[] = [];
  for (const key of fieldPath) {
    if (cur === undefined || !isMap(cur)) {
      throw new Error(`Tried to set field ${key} on non-map value.`);
    }
    cur = cur[key];
    parentPath.push(key);
    if (parentPath.length < fieldPath.length && isArray(cur)) {
      // Note: We're avoiding arrayUnion, arrayRemove, etc. since they may
      // skip adding or / remove all "equal" elements. Checking the edge cases
      // will require implementing Firestore deep equals locally, which is way
      // beyond the scope of this function and hard to keep in sync.
      // Instead, just overwrite the whole array, which may touch more data
      // than needed, but is always correct.
      const pathToUpdate = new firebase.firestore.FieldPath(...parentPath);
      const childPath = fieldPath.slice(parentPath.length);

      // Note: FieldValue sentinels are not guaranteed to be
      // `instanceof FieldValue`, so let's just use type casting here.
      if (value === DELETE_FIELD || DELETE_FIELD.isEqual(value as any)) {
        return [pathToUpdate, withFieldRemoved(cur, childPath)];
      } else {
        return [pathToUpdate, withFieldSet(cur, childPath, value)];
      }
    }
  }
  return [new firebase.firestore.FieldPath(...fieldPath), value];
}