From 14a5b24942b222b229204df805c2d52701fd224d Mon Sep 17 00:00:00 2001 From: BenjaVR Date: Thu, 10 Jan 2019 20:59:23 +0100 Subject: [PATCH] Clean undefined properties when writing to Firestore --- studentplanner.code-workspace | 3 +- web/src/services/FirestoreServiceBase.ts | 49 +++++++++++++++--------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/studentplanner.code-workspace b/studentplanner.code-workspace index 49f5879..7d6c4f9 100644 --- a/studentplanner.code-workspace +++ b/studentplanner.code-workspace @@ -11,6 +11,7 @@ "*.json": "jsonc" }, "npm.packageManager": "yarn", - "typescript.tsdk": "node_modules\\typescript\\lib" + "typescript.tsdk": "node_modules\\typescript\\lib", + "files.autoSave": "onFocusChange" } } diff --git a/web/src/services/FirestoreServiceBase.ts b/web/src/services/FirestoreServiceBase.ts index 0f5a07c..4f15894 100644 --- a/web/src/services/FirestoreServiceBase.ts +++ b/web/src/services/FirestoreServiceBase.ts @@ -2,6 +2,10 @@ import firebase from "firebase"; import { Firebase } from "../config/FirebaseInitializer"; import { FirebaseModelMapper } from "./FirebaseModelMapper"; +interface IObjectToClean { + [key: string]: any; +} + export type OrderByType = "asc" | "desc"; export type ListenOnChangeFunc = (objects: T[], size: number) => void; @@ -32,7 +36,7 @@ export abstract class FirestoreServiceBase { resolve(mappedDoc); }) .catch((error) => { - catchErrorDev(error); + this.catchErrorDev(error); reject(error); }); }); @@ -48,7 +52,9 @@ export abstract class FirestoreServiceBase { obj.createdTimestamp = now; obj.updatedTimestamp = now; - this.collectionRef.add(obj) + const cleanedObj = this.cleanUndefinedFieldsInObjects(obj, false); + + this.collectionRef.add(cleanedObj) .then((docRef) => { return docRef.get(); }) @@ -56,7 +62,7 @@ export abstract class FirestoreServiceBase { resolve(FirebaseModelMapper.mapDocToObject(doc)); }) .catch((error) => { - catchErrorDev(error); + this.catchErrorDev(error); reject(error); }); }); @@ -72,18 +78,12 @@ export abstract class FirestoreServiceBase { delete obj.id; obj.updatedTimestamp = Firebase.firestore.Timestamp.now(); - // Change all "undefined" to "delete()", because Firestore wants this. - const objToClean: { [key: string]: any } = obj; - Object.keys(objToClean).forEach((key) => { - if (objToClean[key] === undefined) { - objToClean[key] = Firebase.firestore.FieldValue.delete(); - } - }); + const cleanedObj = this.cleanUndefinedFieldsInObjects(obj, true); - this.collectionRef.doc(id).update(objToClean) + this.collectionRef.doc(id).update(cleanedObj) .then(() => resolve()) .catch((error) => { - catchErrorDev(error); + this.catchErrorDev(error); reject(error); }); }); @@ -98,16 +98,29 @@ export abstract class FirestoreServiceBase { this.collectionRef.doc(obj.id).delete() .then(resolve) .catch((error) => { - catchErrorDev(error); + this.catchErrorDev(error); reject(error); }); }); } -} -function catchErrorDev(error: any): void { - if (process.env.NODE_ENV === "development") { - // tslint:disable-next-line:no-console - console.log(error); + private cleanUndefinedFieldsInObjects(obj: IObjectToClean, forceDeleteInFirestore: boolean): object { + Object.keys(obj).forEach((key) => { + if (obj[key] === undefined) { + if (forceDeleteInFirestore) { + obj[key] = Firebase.firestore.FieldValue.delete(); + } else { + delete obj[key]; + } + } + }); + return obj; + } + + private catchErrorDev(error: any): void { + if (process.env.NODE_ENV === "development") { + // tslint:disable-next-line:no-console + console.log(error); + } } }