Dumb question, but how to define a field as undefined?
userId: String?
is only resolved to
userId: String | Null
and
userId: String | Undefined
is throwing an syntax error.
Dumb question, but how to define a field as undefined?
userId: String?
is only resolved to
userId: String | Null
and
userId: String | Undefined
is throwing an syntax error.
Hi @Mike! FQL is inspired by but is not Typescript. There is no concept of undefined in FQL, only null. In terms of schema, Null
effectively means missing from the document. null
values are not stored in documents, e.g. setting a field to null
deletes the field in the new document version.
Together, the type String | Null
(or String?
) means that accessing the field may not return a value, but if it does it will be a string.
Are you finding a situation where you are having trouble typing something?
Hi @ptpaterson
Fields set to null won’t be shown during fetch, but computed fields are. Here is an example document that has a field with a null value, instead of being not.
{
data: [
{
testNull: null,
}
]
}
collection Account {
compute testNull: Ref<Account>? = (doc => null)
}
This creates inconsistency trouble if we work with the fauna response in Javascript. As the deleted null field will be treated as undefined
, but the non deleted computed null field will be treated as null
in Javascript.
function createVerification(email: String, userId: String?): String
calling it only with email createVerification("john@doe.com")
throws an not enough arguments error:
invalid_query
error: Function was not called with enough arguments. Expected 2, received 1
at *query*:1:19
|
1 | createVerification("john@doe.com")
| ^^^^^^^^^^^^^^^^^^^^
|
so I need to pass every time null values in comparison to undefined
.
Null vs undefined is definitely a long ongoing discussion in Javascript if this is now for good or for worse, but if you favor lean code, working with null values makes the code more verbose, but also of course more explicit.
With the behavior of the second point I can probably arrange myself, but the first point would be great to have a consistent behavior between fields and computed fields
For dealing with fields that you want to fetch or not fetch you can make sure to use projection. If you happened to project the nullable fields, you will get a null
back in javascript.
Do you typically return the Document type from Fauna? Or an object containing prescripted fields?
One thing I’ve done is to create FQL snippets for projection (reminds me “fragments” in GraphQL). You can provide provide them locally in your client code, like I’ve done here, or create UDFs that format documents into preferred shapes.
Whatever method you use, just be consistent in what you return from the database and the types you use in javascript.
field?: string | null
in JS isn’t fun, but you can force that to field: string | null
and avoid undefined if you always project a nullable field in FQL.
Always including a projection means you don’t always have to include a field. In that example, I had two separate snippets for a User, one without the computed fields, and one with the computed field to fetch relationships.
Regarding function, and this is something we have done internally a lot in our own use of Fauna, is to not accept a list of arguments, but instead accept an object as an argument and take individual inputs from that. This enabled named arguments without the need to worry about order, future maintainability of that order, etc. And you can work with optional arguments this way: don’t include in the object.
function createVerification(input: { email: String, userId: String?}): String