Error Partials
Learning objectives
- You know how to use partials for displaying validation errors.
At the end of the last part, we came up with the following Eta template for displaying the validation errors. The template contains a part that lists validation errors and a part for the form.
<!DOCTYPE html>
<html>
<head>
<title>Hello forms!</title>
</head>
<body>
<% if (it?.errors?.email?._errors) { %>
<p>Email validation errors:</p>
<ul>
<% it?.errors?.email?._errors.forEach((error) => { %>
<li><%= error %></li>
<% }); %>
</ul>
<% } %>
<% if (it?.errors?.yearOfBirth?._errors) { %>
<p>Year of birth validation errors:</p>
<ul>
<% it?.errors?.yearOfBirth?._errors.forEach((error) => { %>
<li><%= error %></li>
<% }); %>
</ul>
<% } %>
<form method="POST" action="/emails">
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="<%= it?.email ?? '' %>" /><br/>
<label for="yearOfBirth">Year of birth:</label>
<input type="number" id="yearOfBirth" name="yearOfBirth" value="<%= it?.yearOfBirth ?? '' %>"/><br/>
<input type="submit" />
</form>
</body>
</html>
As we can observe, the validation errors are almost duplicate code. This is a nice location for using view partials, which we previously looked into when including generic content to pages. Partials are included to a page using the <%~ include('filename') %>
syntax, where filename
corresponds to an Eta file. What we did not previously discuss is that we can pass data to a partial.
We can pass data to a partial.
Data is passed to a partial as an object that is provided as the second parameter to the include
function call. A suitable part for a partial would a part that contains a list of errors for a specific field, i.e.
<% if (it?.errors?.yearOfBirth?._errors) { %>
<p>Year of birth validation errors:</p>
<ul>
<% it?.errors?.yearOfBirth?._errors.forEach((error) => { %>
<li><%= error %></li>
<% }); %>
</ul>
<% } %>
When we consider the above part, there is a list of errors and a name for a field. Let's define a partial called validation-errors.eta
, and save the following content there.
<% if (it?.errors) { %>
<p><%= it.field %> validation errors:</p>
<ul>
<% it?.errors.forEach((error) => { %>
<li><%= error %></li>
<% }); %>
</ul>
<% } %>
The partial expects data that contains an attribute errors
and an attribute field
. The attribute errors
is a list, while the attribute field
is a string. To use the above for replacing the validation errors for year of birth, we would adjust the Eta file as follows.
<!DOCTYPE html>
<html>
<head>
<title>Hello forms!</title>
</head>
<body>
<% if (it?.errors?.email?._errors) { %>
<p>Email validation errors:</p>
<ul>
<% it?.errors?.email?._errors.forEach((error) => { %>
<li><%= error %></li>
<% }); %>
</ul>
<% } %>
<%~ include("/partials/validation-errors.eta", { field: "Year of birth", errors: it?.errors?.yearOfBirth?._errors }) %> <form method="POST" action="/emails">
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="<%= it?.email ?? '' %>" /><br/>
<label for="yearOfBirth">Year of birth:</label>
<input type="number" id="yearOfBirth" name="yearOfBirth" value="<%= it?.yearOfBirth ?? '' %>"/><br/>
<input type="submit" />
</form>
</body>
</html>
Similarly, we can also replace the validation errors for email with the same partial.
<!DOCTYPE html>
<html>
<head>
<title>Hello forms!</title>
</head>
<body>
<%~ include("/partials/validation-errors.eta", { field: "Email", errors: it?.errors?.email?._errors }) %> <%~ include("/partials/validation-errors.eta", { field: "Year of birth", errors: it?.errors?.yearOfBirth?._errors }) %>
<form method="POST" action="/emails">
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="<%= it?.email ?? '' %>" /><br/>
<label for="yearOfBirth">Year of birth:</label>
<input type="number" id="yearOfBirth" name="yearOfBirth" value="<%= it?.yearOfBirth ?? '' %>"/><br/>
<input type="submit" />
</form>
</body>
</html>
The application continues to work as expected, showing the validation errors, but the Eta file is a bit more readable.
curl -X POST -d email="not a valid email" -d yearOfBirth="1899" localhost:8000/emails
<!DOCTYPE html>
<html>
<head>
<title>Hello forms!</title>
</head>
<body>
<p>Email validation errors:</p>
<ul>
<li>Invalid email</li>
</ul>
<p>Year of birth validation errors:</p>
<ul>
<li>Number must be greater than or equal to 1900</li>
</ul>
<form method="POST" action="/emails">
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="not a valid email" /><br/>
<label for="yearOfBirth">Year of birth:</label>
<input type="number" id="yearOfBirth" name="yearOfBirth" value="1899"/><br/>
<input type="submit" />
</form>
</body>
</html>%
This content is restricted based on course progress. Cannot determine the current course progress as the user is not registered (or, it takes a while to load the points). If you have not yet registered, please do so now.