Search code examples
javaspringtwitterspring-bootthymeleaf

How to send variable to controller not as form input in Spring Boot


I am using Spring Boot with Tymeleaf and am fairly new to it. I am using the Twitter API to make an app. I have a list of tweets displayed using th:each. When the user clicks the retweet button for a tweet, that particular tweet's id should be sent to the controller as a parameter for the retweet method, so that it can be processed there. The user should not be aware of the id from the front-end.

As of now my only solution is to include the id as a url in an 'a' tag and have it be taken as a path variable using @PathVariable in the controller and return the index page which has the list of tweets. This works fine but I do not like this method as the user should not have to leave the page and I may later prefer use a modal. Basically I want to know of a way to send the id to the controller without having it displayed in HTML.

index.html

 <div class="result" th:each="result : ${results}">
            <h3><a th:href="${result.fromUser}" th:text="${result.user.name}"></a></h3>

            <p th:text="'@' + ${result.fromUser}"></p>
            <span th:text="${result.text}"></span>
            <div id="retweet">
                    <a th:href="'user/' +  ${result.id}">Retwt</a>

            </div>
        </div>

Maincontroller.java

@RequestMapping(value = "")
public String getUserProfile(Model model) {
    TwitterProfile userInfo = twitterService.getUserProfile();
    List<Tweet> homeTimeline = twitterService.getUserTimeline();
    model.addAttribute("profileImg", userInfo.getProfileImageUrl());
    model.addAttribute("results", homeTimeline);
    return "pages/index";
}

@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public String retweet(@PathVariable long id) {
    twitterService.retweet(id);
    return "/";
}

Solution

  • This can be achieved changing your controller method as bellow and access it using jQuery ajax http GET.

    Changing controller to accept ajax request,

        @ResponseBody    
        @RequestMapping(value = "/user", method = RequestMethod.GET)
        public String retweet(@RequestBody Long id) {
            twitterService.retweet(id);
            return "/";
        }
    

    Change your HTML,

     <div class="result" th:each="result : ${results}">
                <h3><a th:href="${result.fromUser}" th:text="${result.user.name}"></a></h3>
    
                <p th:text="'@' + ${result.fromUser}"></p>
                <span th:text="${result.text}"></span>
                <div id="retweet">
                        <a href="JavaScript:Void(0);" th:onclick="'doRetweet(\'' + ${result.id} + '\');'" >Retwt</a>
    
                </div>
            </div>
    

    JQuery part,

                         function doRetweet(userId){
                            var data = JSON.stringify(userId)
                            if (data) {
                                $.ajax({
                                    url : '/user',
                                    headers : {
                                        'Content-Type' : 'application/json'
                                    },
                                    method : 'GET',
                                    dataType : 'json',
                                    data : data,
                                    success : function(data) {
                                        if (data.status == 200) {
                                            // Handle success response
                                        } 
                                    },
    
                                    error : function(xhr, status, error) {
                                        // Handle errors here
                                    }
                                });
                            }
                        }