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.