Support for serializing undefined values
I like that Convex supports
undefined
as a value via unsetting. I avoid null
throughout my entire app, but that leaves me working around communicating undefined values from the client to the backend.
Would be cool if Convex's react and backend libs could work together to support undefined
as a serializable value, maybe by using a special value under the hood. My current plan is to probably go through my app and use null everywhere that the client wants to send undefined
, and then convert the nulls to undefined in my mutations, but would love to not need to do this.
Also open to smarter workarounds, especially if they save time.5 Replies
Ah interesting. You want to use undefined as a sentinel value to unset through the network protocol.
This makes sense. We'd have to think about this. I think one tricky bit will be what it means for non JS languages. Most languages don't have an explicit undefined, just a concept of nulls, or optional types.
Yeah I wished we only had
null
s in the DB, but undefined
is actually often more ergonomic (you can just leave it out instead of having to set the field to null
). Definitely something we're aware of.Just to state what we do for the dashboard -- we transform
{ foo: undefined }
into { foo: "__PLACEHOLDER_for_undefined" }
before calling the actual mutation, and transform it back in the convex function before calling db.patch
.
This only works with explicitly setting a property to undefined vs. leaving it out ({ foo: undefined, bar: "baz" }
would unset foo
but { bar: "baz" }
wouldn't).
This isn't much different than what you're planning on doing, but mentioning the example anywaysAnd ofc another option is to use
replace
instead of patch
, which will remove any keys that are not present (but might not be workable in your usecase).Every patch would have to effectively be an upsert, if I use replace, so it's a different workaround, but I'd rather do the swap-null-for-undefined dance than have to do a full replace from the client every time
Just a data point, I'm now actively implementing this in my app logic.