Enums in Model Classes
One application of enum types is to represent categories of objects. We will take this approach in our coding-events application to categorize events based on their type, such as conference or meetup.
Enum Types in Models - Video
The starter code for this video is found at the display-errors branch
of the CodingEventsJava repo.
The final code presented in this video is found on the enums branch
. As always, code along to the videos on your own codingevents project.
As mentioned in the previous chapter
, your
display-errors constructor might contain a small quirk. If your
constructor assigns non-sequential id values, this is still OK!
Enum Types in Models - Text
Create an Enum Class
In your models package within codingevents, create a new class called EventType.
Before you finish entering the name of your file, select the Enum option from the list of
types.
Because enum values are constants, we use naming-conventions and write them in all caps. Each value is demarcated with a comma and the list is completed with a semicolon.
EventType:
| |
Add an Enum Field
Enums can store additional information affiliated with each value in fields. Enum fields
are treated like fields on any other type. Again, because enum values are constants, fields
should be final variables, since they will not change.
To add a displayName field to EventType, we declare the field, add a constructor, and
tack on a getter method:
| |
To define the display name for each of the EventType values, we can call the constructor we
just wrote like this:
| |
Add an Enum Property to a Model Class
Other objects can have enum type properties. To add an EventType property to our model Event,
we create a type field in Event amongst the other fields declared:
// other Event field declarations
private EventType type;
// Event methodsWe’ll want to also add this field to the Event constructor, as well as a getter and setter
method:
| |
Pass Enum Values Through the Controller
codingevents uses model binding to create an Event object. So like any other field on
the model, the controller does not necessarily need to know about the addition of Event.type
in order to create an Event instance from a form. However, we want the user to choose from
the pre-defined event type values when creating their event. To do this, we’ll use the
controller method displayCreateEventForm to pass those values into the view.
In EventController:
| |
.values() is a built-in static method that returns an array of values defined in
the given enum, in the order in which they have been declared.
With the template variable types now defined, we can use our EventType values in the view.
Use Enum Value in a Select Element
The list of constants returned from EventType lends itself well to a select-type form
input. We’ll update our form so that a user will have the option to choose one of the provided
event types from a dropdown menu.
In templates/events/create.html:
| |
As with the other form inputs on the page, the th:field attribute determines the name
and id attributes for the select tag. We make an option tag for each of the EventType
values, making use of the types variable we passed in from the controller in the previous step
. We set the value attribute for the
model data to be the EventType value using th:value. And the type name shown to the user
of the form as the displayName of the type, using th:text.
Use Enum Properties to Display Information
Once an event is created, to display its type field in the table of all events, we’ll modify
templates/events/index.html to include another column:
<!-- other table headers -->
<th>Type</th>
<!-- other event data -->
<td th:text="${event.type.displayName}"</td>In this case, the type displayed is the value of the event object’s type field, so the controller
method responsible for rendering this view does not need a types variable passed in. To show the
more user-friendly view of the type value, we use the .displayName field of EventType.
Check Your Understanding
When we add a field to the EventType enum from codingevents, what is the strongest
reason why we don’t we write a setter method for that field?
- Enum classes cannot contain setter methods
- Final variables cannot be reassigned
- Enum fields cannot be reassigned
- We don’t use a setter method in the rest of the application
In coding-events, say we change our template variable name in
EventController.displayCreateEventForm so that EventType.values() is now assigned to
a variable, categories. Which of the template expressions in the following code block
from create.html, if any, should be changed to reflect this update? Select all that apply.
| |
- In line 3,
${event.type}should be changed to${event.category} - In line 4,
type : ${types}should be changed tocategory : ${categories} - In line 5,
${type}should be changed to${category} - In line 6,
${type.displayName}should be changed to${category.displayName}
