Compared to the Minimal App discussed in Chapter 3 we have to deal with a number of new issues:
In the model code we have to add for every property of a class
a check function that can be invoked for validating the constraints defined for the property, and
a setter method that invokes the check function and is to be used for setting the value of the property.
In the user interface ("view") code we have to take care of
responsive
validation on user input for providing
immediate feedback to the user, by invoking
setCustomValidity
together with the corresponding
check function for each input field, and by marking fields with
invalid data with the help of a new CSS style rule
form:invalid {outline: red;
},
validation on form submission for preventing the
submission of flawed data to the model layer by invoking
checkValidity
.
For improving the break-down of the view code, we introduce a
utility method (in lib/util.mjs
) that fills a
select
form control with option
elements the
contents of which is retrieved from an entity table such as
Book.instances
. This method is used both in the
updateBook
and the deleteBook
use
cases.
As a namespace approach (for avoiding name conflicts), we will
now use ES6 modules, instead of a
global namespace object with subnamespace objects, like pl =
{m:{}, v:{}, c:{}}
.
Checking the constraints in the user interface (UI) on user input is important for providing immediate feedback to the user. But it is not safe enough to perform constraint validation only in the UI, because this could be circumvented in a distributed web application where the UI runs in the web browser of a front-end device while the application's data is managed by a back-end component on a remote web server. Consequently, we need multiple constraint validation, first in the UI on input (or on change) and on form submission, and subsequently in the model layer before saving/sending data to the persistent data store. And in an application based on a DBMS we may also use a third round of validation before persistent storage by using the validation mechanisms of the DBMS. This is a must, when the application's database is shared with other apps.
Our proposed solution to this multiple validation problem is to keep the constraint validation code in special check functions in the model classes and invoke these functions both in the UI on user input and on form submission, as well as in the create and update data management methods of the model class via invoking the setters. Notice that referential integrity constraints (and other relationship constraints) may also be violated through a delete operation, but in our single-class example we don't have to consider this.