Search code examples
asp.netajaxasp.net-coremodel-view-controllerrazor

AJAX returns undefined, failure


I am trying to use the success and failure blocks of the AJAX request. My function is working and I can easily direct to the controller and use my queries to modify my SQL database eg. Everything is working, that was the reason about I didn't notice the AJAX response before.

As I said, I can do my operations without problem but my AJAX always returns failure even that my action is working. I didn't understand the way of fixing it, can you take a look at that please?

error

First I tried to log this

console.log('Question sending failed:', result.message);

Question sending ProductDetail?productId=7:2879 failed: undefined

Then I tried to log this

console.log('the entire result: ', result);

the entire ProductDetail?productId=7:2880 result: true

If I log them both at the same time, as a result just this

the entire ProductDetail?productId=7:2880 result: true

You can see the changes in the codes

action

[HttpPost]
[Authorize]
public async Task<IActionResult> SendEmployeeQuestion(SetEmployeeQuestionQuery request)
{
    var result = await MediatrSend(request);
    return Json(result);
}

returns

enter image description here

also "true" for "return Json(Result)"

query

public class SetEmployeeQuestionQuery : IRequest<bool>
    {
        public ClaimModel ClaimModel { get; set; }
        public int ProductId { get; set; }
        public int FirmId { get; set; }
        public string QuestionText { get; set; }
    }

    public class SetEmployeeQuestionQueryHandler : IRequestHandler<SetEmployeeQuestionQuery, bool>
    {
        private readonly IECommerceProductRepository _eCommerceProductRepository;
        public SetEmployeeQuestionQueryHandler(IECommerceProductRepository eCommerceProductRepository)
        {
            _eCommerceProductRepository = eCommerceProductRepository;
        }
        public async Task<bool> Handle(SetEmployeeQuestionQuery request, CancellationToken cancellationToken)
        {
            DateTime currentDateTime = DateTime.Now;
            string formattedTimestamp = currentDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff");

            var questionId = _eCommerceProductRepository.InsertToEmployeeQuestion(request.ClaimModel.EmployeeId, formattedTimestamp).Result;

            await _eCommerceProductRepository.InsertToAnswerLog(null, questionId, request.FirmId, request.QuestionText, null);

            return true;
        }
    }

script

// Ask to seller modal
        $(document).ready(function () {
            $('.ask-button').on('click', function () {
                $('#askToSellerModal').modal('show');
            });

            $('#askToSellerModal').on('hidden.bs.modal', function () {
                clearTextarea();
            });

            $('#sendQuestionButton').on('click', function () {
                var productId = "@Model.ProductData.Id";
                var firmId = "@Model.ProductData.FirmId";
                var questionText = $('#askToSellerTextArea').val();

                $.ajax({
                    type: 'POST',
                    url: '@Url.Action("SendEmployeeQuestion")',
                    data: {
                        ProductId: productId,
                        FirmId: firmId,
                        QuestionText: questionText
                    },
                    success: function (result) {
                    if (result.success) {                           
                        console.log('Question sent successfully:', result.message);
                        console.log('the entire result: ', result);
                    } else {
                        console.log('Question sending failed:', result.message);
                        console.log('the entire result: ', result);
                    }
                },
                    error: function (error) {                       
                        console.error('AJAX error:', error.statusText);
                    }
                });

                clearTextarea();
                $('#askToSellerModal').modal('hide');
            });
        });

        function clearTextarea() {
            document.getElementById('askToSellerTextArea').value = '';
        }

Solution

  • That's possibly because in your async Task<IActionResult> SendEmployeeQuestion, you are returning a result but you don't set a status and a message so you can handle it afterwards on your AJAX response. You are not passing a message to your response. Thus, you would need to change a bit your function to be able to use to this manner.

    I have put a try catch exception block to your HttpPost function so you can handle the errors when the request fails. That means that it will enter inside the error block of your AJAX.

    As you didn't mention what does your MediatrSend function does, I assumed that it sends a back an HttpStatusCode.

         public class BaseResponse
        {
           public bool status { get; set; }
           public string message { get; set; }
       }
    
    
         [HttpPost]
         [Authorize]
         public async Task<IActionResult> SendEmployeeQuestion(SetEmployeeQuestionQuery request)
         {
    
           BaseResponse resp = new BaseResponse();
           try {
                var resultContent = await MediatrSend(request);
                var jsonResponse = resultContent.Content.ReadAsStringAsync();
    
                if (result.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    resp = JsonConvert.DeserializeObject<BaseResponse>(jsonResponse.Result);
                    resp.status = true;
                    resp.message = "Success message.";
                }
                else
                {
                    resp = new BaseResponse();
                    resp.status = false;
                    resp.message = "error message";
                }
           } catch (Exception ex) {
                resp = new BaseResponse();
                 resp.status = false;
                resp.message = $"error in response {Ex.Message}"; 
            }
          
           return resp;
        }
    

    Therefore, your AJAX code should be written like this:

                  $.ajax({
                    type: 'POST',
                    url: '@Url.Action("SendEmployeeQuestion")',
                    data: {
                        ProductId: productId,
                        FirmId: firmId,
                        QuestionText: questionText
                    },
                    success: function (result) {
                      if (result.status === true) {                           
                        console.log('Question sent successfully:', result.message);
                        console.log('the entire result: ', result);
                       } else {
                        console.log('Question sending failed:', result.message);
                        console.log('the entire result: ', result);
                       }
                    },
                    error: function (error) {                       
                        console.error('AJAX error:', error.message);
                    }
                });
    

    I hope that my example can more or less guide you to find a solution to your problem.