I got this dropdown that will be utilized on some pages and I am concerning if I should componentize it and include it on each page or if I call the dropdown service on each service that is needed. I building a spring mvc with thymeleaf
-
if you have the same dropdown (with the same items) on several pages, then perhaps you can place it in a thymeleaf fragment and include that fragment wherever needed. This way, if you ever need to change that dropdown you can do it in one, instead of, several places. – dsp_user Jan 24 '23 at 18:24
-
it make sense but how could I pass the data to the fragment without having to call the dropdown service on each controller page? is it possible? – user2566397 Jan 24 '23 at 19:23
-
does your dropdown contain dynamic data, which change between different pages? If so, than you'll obviously have to call the dropdown service for every page. – dsp_user Jan 25 '23 at 09:21
-
no it doesnt it is the same data – user2566397 Jan 25 '23 at 11:28
-
1if your data doesn't change, then perhaps you can store them in a session variable (javax.servlet.http.HttpSession), which can then be referenced from thymeleaf (e.g ${session.dropdownList} ) – dsp_user Jan 25 '23 at 11:44
-
oh that might work, thanks...any idea on how I could refresh the data? cause it is the same data for all pages but it is dynamic meaning that I could add new entries for the dropdown – user2566397 Jan 25 '23 at 14:09
-
no shortcuts here, you will have to call the dropdown service any time your data have changed. So just update the session any time your data have changed. – dsp_user Jan 25 '23 at 14:25
-
that data could be updated by other app/process, is there any place where I could hook my code to update the session? – user2566397 Jan 25 '23 at 14:35
-
have a look here https://stackoverflow.com/questions/33911341/spring-getting-notified-on-db-changes. I haven't used any of these options myself – dsp_user Jan 25 '23 at 14:41
-
I was looking for something on the Spring lifecycle, the notification from db might work but it kinda defeat the purpose of easy maintainability of the dropdown I think I go with the code duplication approach since my app is not large enough for this complexity. Thanks for your inputs @dsp_user – user2566397 Jan 25 '23 at 17:40
-
@dsp_user post your approach as an answer so we can help others – user2566397 Jan 25 '23 at 17:42
1 Answers
In case when you have a dropdown, or any other html element for that matter, that needs to appear on several pages, it makes sense to place that element(s) inside a thymeleaf fragment so as to avoid code duplication. Not only do you avoid code duplication, but your code will become easier to maintain as well (because there's less code to maintain).
<div th:fragment="dropdownFragment">
....
<select>
<th:block th:each="item : ${dropdownItems}">
<option th:value="${item}" th:text="${item}"></option>
</th:block>
</select>
</div>
In order to reduce the number of trips to the database, we should cache our data. Possibly the easiest way to do this is to make use of the built in HttpSession object (especially when our data is relatively small).The code might look something like
HttpSession session = request.getSession();
//code to retrive data from the db
session.setAttribute("dropdownItems", dropdownItems);
The session object can be referenced in thymeleaf as #{session.some_object}
but this has been deprecated since Thymeleaf 3.1. For this reason, it's best to copy the session attribute into a Model (or ModelAndView) object, which can then be referenced as ${modelObject}
.
@GetMapping("/getItems")
public ModelAndView getDropdownItems(HttpSession session )
ModelAndView mv = new ModelAndView();
mv.setViewName("someView");
//this assumes that you already have a session with dropdownItemsattribute
mv.addObject("dropdownItems", session.getAttribute("dropddownItems"));
return mv;
}
Hope this helps.

- 2,061
- 2
- 16
- 23