Tips for resolving the problem when encountering the "undefined data" issue in the success callback of an AJAX request

I am facing an issue with my JSP page where I have a button that calls an Ajax method named "sendmail()" upon click. The send mail API is in the Controller, and I am trying to display an alert message in the Ajax success function using data.message, but it shows that data is undefined.

I attempted to set the response object in the controller with a message string as 'success' and return it as a string. Please note that to achieve this, I had to change the return type of my controller's sendmail method to String. However, I noticed that the Ajax call does not enter the success function in this scenario. It works fine when the method has a void return type. Upon checking with the Chrome Developer tools, the network call returns a 404 error (not found). The email is sent successfully, but the Ajax success function is not triggered.

Below is the code snippet for the button and Ajax method:

<div class="uk-width-large-2-5">

  <div class="uk-form-row">
  <label>Message</label>
  <textarea id="message" cols="30" rows="4" class="md-input"></textarea>
  </div>
  <div class="uk-form-row">
  <button type="submit" class="md-btn md-btn-success md-btn-large" onclick="sendMail()">Send Message</button>
 </div>
 </div>

Ajax method :

<script>
function sendMail() {
 var reqJson = {};
 reqJson.msg = $("#message").val();


$.ajax({
type : "POST",
url : "sendMail",
data : JSON.stringify(reqJson),
dataType: 'json',
contentType: "application/json",
  success : function(data) {    
  console.log("data :"+data.message);
               }
 error: function()
 {
}
    });                                 
}
</script>

Maincontroller.java

 @RequestMapping(value = "/sendMail", method = RequestMethod.POST, produces = "application/json")
   public void sendContact(HttpServletRequest request, HttpServletResponse response, @RequestBody String payload) {
        JSONObject jRespObj = new JSONObject();

      try {
        System.out.println("Welcome");
        JSONObject jPayload = new JSONObject(payload);
         System.out.println("jobj : "+jPayload);
         String message = jPayload.getString("msg");
         InputStream inputStream = UserController.class.getResourceAsStream("/Contactusrequest.htm");
      StringWriter writer = new StringWriter();
      try {
          IOUtils.copy(inputStream, writer);
         } catch (IOException e) {
          e.printStackTrace();
         }
      HttpSession session = request.getSession(true);

        String from = (String) session.getAttribute("email");
        String to ="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1068696a507172733e737f7d">[email protected]</a>";
        String emailContent = writer.toString();
        emailContent = emailContent.replace("replaceMeFromEmail",from);
        emailContent = emailContent.replace("replaceMeToEmail", to);
        emailContent = emailContent.replace("replaceMeReason", message);

         emailClient.sendMail("", to, null, "Contact Us Request", emailContent);
        jRespObj.put("message", "Mail sent successfully");
        response.setStatus(HttpServletResponse.SC_OK);

     } catch (Exception ex) {
          ex.printStackTrace();
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
     }
    return jRespObj.toString();
   }

I am looking to receive the response object from the controller in the Ajax success callback to access the data.message.

Answer №1

Solution 1. When working with Ajax, be cautious of undefined errors when returning the response. To avoid this issue, consider writing the JSON response in the body using Gson or JSONObject instead of simply returning it.

For example.

//Write the json response in body
  //return jRespObj.toString();
  response.getWriter().write(jRespObj.toString());

Solution 2 - Eliminate all other System.out.println statements and present a single response in JSON format like so:

System.out.print(jRespObj.toString());

When working with Ajax, you can retrieve the response using the following code snippet:

$ajax({
----
success : function(data) {    
  console.log("data :"+data['message']);
},
 error: function()
 {
}

Answer №2

After much trial and error, I finally discovered the solution: By adding @Responsebody and parsing the data received in Ajax success, I was able to make everything work smoothly. Here is the code snippet:

@RequestMapping(value = "/sendMessage", method = RequestMethod.POST)
@ResponseBody
public String sendMessage(HttpServletRequest request, HttpServletResponse response, @RequestBody String payload) throws JSONException, IOException {
    JSONObject jRespObj = new JSONObject();

    try {
        System.out.println("Welcome");
        JSONObject jPayload = new JSONObject(payload);
        System.out.println("jobj : " + jPayload);
        String message = jPayload.getString("message");

        InputStream inputStream = UserController.class.getResourceAsStream("/Contactusrequest.htm");
        StringWriter writer = new StringWriter();
        
        try {
            IOUtils.copy(inputStream, writer);
        } catch (IOException e) {
            e.printStackTrace();
        }

        HttpSession session = request.getSession(true);
        String from = (String) session.getAttribute("email");
        String to ="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="760e0f0c36131a1315020419181905191a03021f1918055815191b">[email protected]</a>";
        
        String emailContent = writer.toString();
        emailContent = emailContent.replace("replaceMeFromEmail",from);
        emailContent = emailContent.replace("replaceMeToEmail", to);
        emailContent = emailContent.replace("replaceMeReason", message);
        
        emailClient.sendMail("", to, null, "Contact Us Request", emailContent);
        jRespObj.put("message", "Mail sent successfully");

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    
    return jRespObj.toString();
}

Ajax process:

<script>
function sendMessage() {
    console.log("page load");

    var reqJson = {};
    reqJson.message = $("#message").val();
    
     $.ajax(
     {
         url : "sendMessage/",
         type: "POST",
         data : JSON.stringify(reqJson),
         contentType: "application/json",
         success:function(data)
         {
            var msg = JSON.parse(data);
            console.log(msg);

            UIkit.notify('<a href="#" class="notify-action">Clear</a> ' + msg.message, {
             pos : 'top-center',
             status:'success',
             timeout : 2000
           });

          setTimeout(function(){ location.reload(); }, 2000);
         }, 
         error: function(data)
         {

           UIkit.notify('<a href="#" class="notify-action">Clear</a> ' + "Mail not sent", {
             pos : 'top-center',
             status:'warning',
             timeout : 6000
           }); 
         }
       });

    }
 </script>   

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Are Updatepanel and Scriptmanager necessary components in ASP.NET to enable AJAX functionality?

Has anyone had success using the scriptmanager and updatepanel for AJAX implementations in ASP.NET? Are these necessary to achieve partial page updates and reference handlers like button1_click on the server code page? Another question I have is whether t ...

When using the Parse JS SDK with AngularJS UI routing, the login functionality may not properly retain the current user's

Below is the configuration and initialization of my module: angular.module('FXBApp', [ 'ui.bootstrap' ,'ui.router' ,'oc.lazyLoad' ,'parse-angular' ]). config(['$urlRouterProvider','$statePro ...

Using the Ajax method from a separate class in TypeScript: A step-by-step guide

Recently, I started learning about typescript and ajax. One of the challenges I encountered was while creating a method in typescript for making ajax calls that can be used across classes: myFunc(value: string): JQueryPromise<any> { var dfd = $. ...

What is the best way to activate CSS filters on VueJS once the project has been compiled?

While working on a Node server locally, my SVG filter functions properly. However, once I build the project and run it on a server, the filter stops working. This VueJS project is utilizing Webpack as its build tool. The process of building the app invol ...

Is it possible to activate the identical drop-down or popover with multiple buttons?

Is it possible to activate the same drop-down menu with multiple buttons? For example, I want a button at the top of the page labeled special menu, another in the middle also labeled special menu, and one at the bottom as well labeled special menu. When a ...

Validation of forms on the client side using Angular in a Rails application

I'm facing an issue with implementing client-side validations for a devise registration form using Angular. Although I am able to add the "invalid" class to the fields as expected, I am struggling to get any output when using ng-show. There are no oth ...

How can one properly extend the Object class in JavaScript?

I have a scenario where I want to enhance a record (plain Javascript object) of arrays with additional properties/methods, ideally by instantiating a new class: class Dataframe extends Object { _nrow: number; _ncol: number; _identity: number[]; co ...

What is the best way to store and serve the AngularJS library locally in a static manner?

I have a project in Angular that needs to be developed without an internet connection, which means the CDN links will not work. I want to save the AngularJS library to a directory within my project. This is what I attempted: First, I visited the CDN link, ...

Using the Twit package on the client side: a step-by-step guide

I have been utilizing the Twit package for searching tweets. After executing the js file in the console, I am able to see the tweets but when trying to use them on my webpage, an error 'Uncaught ReferenceError: require is not defined' pops up. Th ...

Experiencing a challenge with Express and PassportJs when using the Google OAuth2.0 strategy as it's not providing the

Currently, I am in the process of configuring an authentication route for our application. Unfortunately, I am facing a challenge with the Google oAuth 2.0 strategy for PassportJs as it does not provide me with a req.user object when using sequelize. Below ...

Learn how to display a "not found" message in a React.js application

I have a piece of code where I am sending a post request to an API and retrieving all the data from the API in a table. I am trying to find currency data based on the currency name, if found I display the data in a div, if not found I want to print "not ...

sending a form to the server using AJAX and PHP

Trying to submit a basic contact form using AJAX. UPDATED CODE Currently attempting to insert the data into a database. HTML Form <form align="left" method="post" class="subscribe_form" action='subscribe.php'> ...

Examining the dimensions of a div element in AngularJS

As I delve deeper into understanding AngularJS and tackling the intricacies of how $watch operates, a specific scenario has caught my attention. I want to monitor and track changes in the dimensions of the div element with an ID of "area". My intention is ...

Send the form using an alternative method to avoid using preventDefault

Having some trouble with my website's sign-in functionality not working properly on all browsers. In Firefox, I keep getting a "ReferenceError: event is not defined" error. I've read through various posts about preventDefault behaving differentl ...

Having trouble incorporating a variable into the Discord Client object in Typescript

As a newcomer to Typescript, I am working on creating a Discord bot using Typescript. I am trying to add a variable called "commands" to the Client object. In JavaScript, you can achieve this using the following code: Javascript const { Client } = require ...

Issue with Angular 12 service worker causing SW update to fail

I'm currently working on integrating a service worker into my Angular application to enable updates without user intervention. Here is the step-by-step process that I am following: Make changes to the application Run ng build Start an HTTP ser ...

Error message indicating that the function is not defined within a custom class method

I successfully transformed an array of type A into an object with instances of the Person class. However, I'm facing an issue where I can't invoke methods of the Person class using the transformed array. Despite all console.log checks showing tha ...

Vue 2.0: Exploring the Power of Directive Parameter Attributes

It has come to my attention that directive param attributes have been phased out in Vue.js 2.0. As a result, I am unable to use syntax like v-model="msg" number within an input tag. Are there alternative methods to achieve the same outcomes without relyi ...

Tips for making jQuery maphilight function properly?

Can someone assist me with Mapilight? I have been trying to get it to work but no success so far. Here are the script links in the head section of my HTML. <script type="text/javascript" src="/js/jquery.js"></script> <script type="text/ja ...

Developers specializing in Google Maps navigate to a particular destination

I have been working on an app that provides users with the best options for places to visit, utilizing Google Maps technology. Here is what I have accomplished so far: Show the user their current location Show the user possible destinations (with marker ...