Thymeleaf fragment is loaded before method is executed

Quetsalkoatl :

I have a Controller like this:

@Controller
public class DeviceController {

  @Inject
  private DeviceService deviceService;

  @ModelAttribute("devices")
  public List<Device> getDevices() {
    return deviceService.getAll();
  }

  @GetMapping({"/", "index.html"})
  public String showIndex() {
    return "index";
  }

  @DeleteMapping(value = "/devices/{id}")
  public String deleteOne(@PathVariable("id") long id) {
    deviceService.deleteOne(id);
    return "index :: devices";
  }
}

And a Thymeleaf template like this:

<table id="tbl_device" th:fragment="devices">
  <tr> <!-- header --> </tr>
  <tr th:each="e : ${devices}" th:object="${d}" th:id="'device_' + *{id}" th:fragment="'device_' + *{id}">
    <!-- columns -->
  </tr>
</table>

When I call the /devices/{id} DELETE endpoint, I would expect it to return the table without the deleted device. But it actually returns the table including the deleted device. When I debug the code, I can see that getDevices() is called before deleteOne(id).

When I manually reload the page after deleting, the row is (correctly) not displayed anymore.

Why is that? And (how) can I change this behaviour?
Thanks

Jakub Ch. :

Why is that?

I recommend to read this article. According to that:

In general, Spring-MVC will always make a call first to that method, before it calls any request handler methods. That is, @ModelAttribute methods are invoked before the controller methods annotated with @RequestMapping are invoked. The logic behind the sequence is that, the model object has to be created before any processing starts inside the controller methods.

I doubt you can alter invocation order, but what you can do is additionally pass model attribute to your deleteOne method and modify it there.

@DeleteMapping(value = "/devices/{id}")
public String deleteOne(@PathVariable("id") long id, @ModelAttribute("devices") List<Device> devices) {
    deviceService.deleteOne(id);
    devices.remove( /* just deleted device */);
    return "index :: devices";
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=152761&siteId=1