Populate table using Ajax XMLHttpRequest() with JSON data from Spring backend

Viewed 704

I'm building a Spring Boot project for which I've been using Thymeleaf to render my views. For one of the datasets I wanted to be more fancy and instead of returning the Thymeleaf template in GET method with data (using model.addAtribute() etc.), I'd like to return the dataset in JSON format using ResponseEntity and pass that data set to my view using Ajax XMLHttpRequest() object.

Unfortunately, when I enter my desired endpoint, the view doesn't render, but instead I get the JSON data displayed on the screen - I sort of understand why this happens, but wonder how I can render the view in that case. Therefore, here is my kindest request: Could you give me a hint how I should handle that + take a look on my js file with ajax if it looks all right.

So maybe first let's have a look how I would have done that with Thymeleaf (And it works fine, as the view renders):

    @GetMapping("/auth/admin/guests")
    public String getGuestsDashboard(Model model) {
        model.addAttribute("guests", guestService.getAllGuestsWithoutDetails());
        return "admin/manageguests";
    }

I would like not to use Thymeleaf, so my current way is as follows:

Spring Controller returning data in JSON format

    @GetMapping("/auth/admin/guests")
    public ResponseEntity<String> getAllGuests2() throws JsonProcessingException {
        List<GetGuestsDto> guests = guestService.getAllGuestsWithoutDetails();
        LOG.info("Guest list: {}: ", guests.toString());
        if(!guests.isEmpty()) {
            return ResponseEntity.status(HttpStatus.OK).body(toJson(guests));
        } else {
            return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
        }
    }

    private String toJson(Object object) throws JsonProcessingException
    {
        return new ObjectMapper().writeValueAsString(object);
    }

JavaScript script (guest-admin.js) with a function fetching data from the Spring backend* Could you also please take a look on the JS template literals (backticks).

let GuestAdminUtils = {

    getAllGuestsWithoutDetails : function() {

        let xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://localhost:8081/auth/admin/guests', true);

        xhr.onload = function() {
            if(this.status === 200) {
                let guests = JSON.parse(this.responseText);
                console.log(guests)
                let output = '';
                for(let i in guests) {
                    output +=
                        `<tr>
                            <td>${guests[i].id}</td>
                            <td>${guests[i].lastName}</td>
                            <td>${guests[i].firstName}</td>
                            <td>${guests[i].emailAddress}</td>
                            <td>${guests[i].active}</td>
                         </tr>`;
                }
                document.getElementById('guestTableBody');
            }
        }
        xhr.send();
    }
}
GuestAdminUtils.getAllGuestsWithoutDetails();

Part of the html view (manageguests.html) with table to be populated I have attached the srcipt at the bottom of the view.

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">

<head th:replace="fragments/dashboardhead"></head>

<body>
             <div class="table-responsive">
                <table id="guestTable" class="table table-striped table-sm">
                    <thead>
                    <tr>
                        <th>Id</th>
                        <th>LastName</th>
                        <th>FirstName</th>
                        <th>Email</th>
                        <th>Status</th>
                        <th>Delete</th>
                        <th>Deactivate account</th>
                    </tr>
                    </thead>
                    <tbody id="guestTableBody">

                    </tbody>
                </table>
            </div>


<script src="/static/scripts/guest-admin.js"></script>
<footer th:replace="fragments/footer"></footer>
</body>
</html>

So when I enter the URL http://localhost:8081/auth/admin/guests I only get the JSON data displayed in the web browser, not the entire view with table etc.

Wondering if I'm thinking correctly or not.

Update #1:

As the response to the questions - that is the json data I get. So basically, I enter the endpoint /auth/admin/guests and this is displayed in the browser - NOT in the console, but in the body. I have also added console.log(guests) in the js file (inside the if-statement), but nothing is displayed in the console, so my data doesn't seem to be reaching the script, perhaps...

[{"id":1,"lastName":"Brown","firstName":"Andrew","emailAddress":"andrew.brown@yahoo.com","active":true},{"id":2,"lastName":"Smith","firstName":"Michael","emailAddress":"michael.smith@gmail.com","active":true}]
1 Answers

So, after more research I decided to do that the following way (and it works as desired!):

  1. I added a method 'getGuestsDashboard', which returns just a view (url: /auth/admin/guests)
  2. Also kept the 'getAllGuests' method fetching data and returning JSON, but that is available under the uri: /auth/admin/guests/getall, which I'm calling in my ajax part.
Related