Type safety
Required
Summary
In this lesson, we explore the required
property in Waterline models, which ensures that specific attributes must always have a value when a record is created. Unlike defaultsTo
, which provides a fallback value if an attribute is missing, required
enforces that the attribute is explicitly set by the user. These two properties are mutually exclusive—an attribute cannot have both required: true
and defaultsTo
simultaneously. The lesson demonstrates how to define required attributes, test record creation, and handle validation errors when required values are missing.
Transcript
So let’s look at the flip side of the defaultsTo
property—the required
property.
In the previous lesson, we saw that defaultsTo
allows an attribute to have a default value when it is not explicitly provided during record creation. The required
property, on the other hand, enforces that an attribute must always have a user-provided value.
This means that whenever you create a record using User.create()
, attributes marked as required
must be included. Otherwise, Waterline will throw an error. This ensures that critical data fields never end up as null
or empty strings.
Let me show you an example. If we check our model definition, we currently have defaultsTo
properties. However, you cannot use defaultsTo
and required
together on the same attribute—because you can’t require a value while also providing a default. You have to choose one or the other.
Let’s say we want to ensure that every user has a first name and last name. We can enforce this requirement in our model:
firstName: {
type: 'string',
required: true
},
lastName: {
type: 'string',
required: true
}
Now, let’s try creating a user without specifying firstName
and lastName
:
await User.create({}).fetch();
Waterline will throw an error:
Missing value for required attribute `firstName`
Expected `string` but instead got `undefined`
You can see that it stops at the first missing required attribute. If we provide firstName
but still omit lastName
:
await User.create({ firstName: 'Abel' }).fetch();
Waterline will now throw an error for lastName
, meaning it checks each required attribute in sequence.
Using required
is a great way to protect the integrity of your data and ensure that records always contain the necessary information. If an attribute is essential to your app, marking it as required
ensures it’s always present when records are created.
Full Course
USD