Jack Shepherd
Jack Shepherd

Reputation: 393

JSON.parse error upon returning PartialView from controller

I have the following ajax call

    $.ajax({
        type: "POST",
        url: url,
        dataType: "json",
        data: { occupants: occupants },
        success: function (data) {
            $("#summaryContent").html(data);
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.log("Status: " + textStatus);
            console.log("Error: " + errorThrown);
        }
    });

And a controller that looks like this

    [HttpPost]
    public PartialViewResult Verification(List<OccupantDto> occupants)
    {
        //do stuff
        return PartialView();
    }

And I'm getting this error in my ajax call

Error: SyntaxError: JSON.parse Error: Invalid character at position:5

I tried removing dataType: "json" from my ajax call, that removes the error, and it renders my partial view, however, in my controller, occupants is an empty list. Adding dataType: "json" populates occupants in my controller, but throws me an error.

Upvotes: 0

Views: 1847

Answers (1)

Shyju
Shyju

Reputation: 218732

This part in your $.ajax method call

dataType: "json",

tells jQuery that you are expecting the result from server as a valid json string. So jQuery will try to explicitly parse it to a js object (using JSON.parse() method) with the assumption that it is a valid JSON string response came back because you assured jQuery that using the dataType: "json" option.

But in your case you are returning a view result, which is just HTML markup. So it cannot be parsed to a javascript object. JSON.parse() will throw a SyntaxError exception if the string to parse is not valid JSON. That is what you are getting because the parse method call crashed, hence it executes the error handler of your $.ajax method.

Simply remove that line which specifies the dataType line. This should work

$.ajax({
    type: "POST",
    url: url,
    data: { occupants: occupants },
}).done(function (data) {
    $("#summaryContent").html(data);
}).fail(function (XMLHttpRequest, textStatus, errorThrown) {
    console.log("Status: " + textStatus);
    console.log("Error: " + errorThrown);
});

In most of the cases, you do not need to necessarily specify the dataType property value. If nothing is specified jQuery will try to infer it based on the mime type of the response coming back.

Now, As long as you have a valid array of items (matching with the structure of OccupantDto), Your occupants parameter will be properly mapped by model binder and will not be null/empty collection.

Assuming OccupantDto has an Id and Name property (which is settable public properties), This should work

var occupants = [{ name: "Scott",id:4},{ name: "Shyju",id:6}];
$.ajax({
    type: "POST",
    url: '@Url.Action("Verification")',
    data: { occupants: occupants }
})

As of jQuery 3.0, the success(), error() and complete() callbacks are removed . You may use done(), fail(), and always() instead.

Upvotes: 3

Related Questions