# Validation
Validating user entered data is usually required both on the client-side and on the server-side, often causing a violation of the DRY (opens new window) design principle. With Remult, validation code can be placed within the entity class, and Remult will run the validation logic on both the frontend and the relevant API requests.
# Validate the Title Field
Task titles are required. Let's add a validity check for this rule, and display an appropriate error message in the UI.
- In the
Task
entity class, modify theFields.string
decorator for thetitle
field to include an object literal argument and set the object'svalidate
property toValidators.required
.
src/shared/Task.ts
@Fields.string({
validate: Validators.required
})
title = '';
Import Validators
This code requires adding an import of Validators
from remult
.
- In the
App.tsx
template, modify thesaveTask
function to catch exceptions.
src/App.tsx
const saveTask = async () => {
try {
const savedTask = await taskRepo.save(task);
setTasks(tasks.map(t => t === task ? savedTask : t));
} catch (error: any) {
alert(error.message);
}
}
Manual refresh required
For this change to take effect, you must manually refresh the browser.
After the browser is refreshed, try creating a new task
or saving an existing one with an empty title - the "Should not be empty" error message is displayed.
# Implicit server-side validation
The validation code we've added is called by Remult on the server-side to validate any API calls attempting to modify the title
field.
Try making the following POST
http request to the http://localhost:3002/api/tasks
API route, providing an invalid title.
curl -i http://localhost:3002/api/tasks -H "Content-Type: application/json" -d "{\"title\": \"\"}"
An http error is returned and the validation error text is included in the response body,
# Custom Validation
The validate
property of the first argument of Remult
field decorators can be set to an arrow function which will be called to validate input on both front-end and back-end.
Try something like this and see what happens:
src/shared/Task.ts
@Fields.string<Task>({
validate: (task) => {
if (task.title.length < 3)
throw "Too Short";
}
})
title = '';