Search code examples
jqueryajaxgrailsgrails-controller

Grails controller sending weird JSON back to browser


I have a Grails (2.3.6) app serving an HTML form with two <select/> elements in it: one that allows users to select a country and then, subsequently, a state. When the user selects a new country, I want to update the state select element. To do this, on country change(), I need to ask the server for the new list of state options to populate the state <select/> with:

<div class="blah">
    <label for="state">State</label><br/>
    <g:select id="state" name="state" from="${states}" />
</div>

<script type="text/javascript">
    jQuery('#country').change(function() {
        var countryName = $('#country option:selected').val();

        jQuery.ajax({
            url: "getStateListByCountry",
            type:"get",
            dataType: 'json',
            data: {
                countryName: countryName
            },
            success: function(data) {
                alert("Received following from server: " + data);

                $("#state option").remove();

                $.each(data, function(key, value) {
                    $('#state')
                        .append($("<option></option>")
                        .attr("value",key)
                        .text(value));
                });
            },
            error: function(xhr){
                alert(xhr.responseText); //<----TODO: Replace
            }
        });
    });
</script>

And then, on the Grails/server side:

class MyController {
    // Stub this with dummy data to return.
    def getStateListByCountry() {
        List<String> states = new ArrayList<String>()
        states.add("NY")
        states.add("NH")
        states.add("VT")

        println "Sending the following back to browser: ${states}."

        states
    }       
}

At runtime, when I select a new country in the '#country' select, I see the following message in the Grails app log:

Sending the following back to browser: [NY, NH, VT].

But then in the browser I get an alert(...) that prints the HTML of my custom "Page Not Found" error page!

Furthermore my '#state' select doesn't update with the 3 dummy state values. So the Grails server is correctly receiving the client request, and trying to send back my dummy state list, but somewhere along the way a "Page Not Found" template is getting returned. Any ideas as to what is going on here or what is wrong with my code?


Update

It seems that my error function is executing, and the bizarre HTML I've been seeing inside the alert is actually the xhr.responseText passed into that method.

The Grails server isn't reporting any errors in the logs, and a println in the getStateListByCountry method confirms that the JSON being returned to the client is ["NY","VT","NH"]. So it seems that the server is returning an error somehow, and jQuery is executing the error handler, not the success handler...ideas?


Solution

  • The problem was on the client-side. I had specified a dataType of "json" but was not returning JSON via the Grails render(...) method.