Home > OS >  Easy Notation for Optional Addition to an Object?
Easy Notation for Optional Addition to an Object?

Time:05-28

I have a service with some optional inputs that are passed in depending on which form is calling the service. If I try and run this without the sid an eid inputs, the actual .add({}) to firestore with an error about undefined for the field, which makes some sense.

Unsupported field value: undefined (found in field eventId in document

So, I can think of several ways using various expressions and if statements, or writing 2 different variations on the service that can be called from the different locations, but I was hoping for a more elegant solution.

Is there an easy way, like the '?' you can use in interfaces or in inputs to indicate that this field is optional?

like: { ...inventoryAdd, ...timestamp, ...?sessionId, ...?eventId }

Or, do I just need to write some logic, or split out the function into two?

  addInventory(inventoryAdd: any, pid: string, sid?: string, eid?: any) {
    const inventoryCollectionRef = this.afs.collection("/Party-Management/"   pid   "/Party-Inventory");
    const timestamp = { timestamp: firebase.firestore.FieldValue.serverTimestamp() }
    const sessionId = { sessionId: sid}
    const eventId = { eventId: eid }
    inventoryCollectionRef.add({ ...inventoryAdd, ...timestamp, ...sessionId, ...eventId })
  }

CodePudding user response:

I'd probably just use if statements (but keep reading):

addInventory(inventoryAdd: any, pid: string, sid?: string, eid?: any) {
    const inventoryCollectionRef = this.afs.collection("/Party-Management/"   pid   "/Party-Inventory");
    const toAdd = {
        ...inventoryAdd,
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
    };
    if (sid) {
        toAdd.sessionId = sid;
    }
    if (eid) {
        toAdd.eventId = eid;
    }
    inventoryCollectionRef.add(toAdd);
}

But if you want to do it with expressions instead, spreading null is a no-op, so you could set sessionId/eventId to null when you don't have sid/eid (see ***):

addInventory(inventoryAdd: any, pid: string, sid?: string, eid?: any) {
    const inventoryCollectionRef = this.afs.collection("/Party-Management/"   pid   "/Party-Inventory");
    const timestamp = { timestamp: firebase.firestore.FieldValue.serverTimestamp() };
    const sessionId = sid ? { sessionId: sid} : null;   // *** 
    const eventId = eid ? { eventId: eid } : null;      // ***
    inventoryCollectionRef.add({ ...inventoryAdd, ...timestamp, ...sessionId, ...eventId });
}

Spreading undefined is also a no-op, as is spreading an empty string, so you could also do it like this (see ***):

addInventory(inventoryAdd: any, pid: string, sid?: string, eid?: any) {
    const inventoryCollectionRef = this.afs.collection("/Party-Management/"   pid   "/Party-Inventory");
    const timestamp = { timestamp: firebase.firestore.FieldValue.serverTimestamp() };
    const sessionId = sid && { sessionId: sid};   // *** 
    const eventId = eid && { eventId: eid };      // ***
    inventoryCollectionRef.add({ ...inventoryAdd, ...timestamp, ...sessionId, ...eventId });
}

That works because x && y evaluates x and if x is falsy takes the value as its result, otherwise it evaluates y and takes that as its result. So if sid/eid is undefined or "", sessionId/eventId is undefined or "" (and spreading them doesn't put anything in the object); otherwise, they're the objects and spreading them adds their properties to the object.

  • Related