1

I have a change/getJson function that looks like this:

$('#CountryId').change(function () {
            $.getJSON('@Url.Action("StateList", "Manage")', {id: $('#CountryId').val()}, function (data) {
                var items = '<option value="">Select a State</option>';
                $.each(data.List, function (i, state) {
                    items += "<option value='" + state.Value + "'>" + state.Text + "</option>";
                });
                $('#StateId').html(items);
              //Fail
                //console.log(">>>>" + data.LatLng.Latitude);
                //$('#Latitude').val(data.LatLng.Latitude);
              //Success
                //$.each(data.LatLng, function (i, country) {
                //    $('#Latitude').val(country.Latitude);
                //    console.log(">>>>" + country.Latitude);
                //});
                $('#CityId').html('<option value="">Select a City</option>');
            });
        });

The data is coming back from my json result fine. It's returning a statelist for that CountryId (CountryId is FK from the States table) to build my selectlist/dropdownfor control. It is also returning the Latitude and Longitude for the CountryId (From the Countries table). The State list for my selectlist is fine. However, the Latitude and Longitude will only ever be one set of values (i.e. one record). The only way I can get it to work in jquery is with the .each loop:

$.each(data.LatLng, function (i, country) {
   $('#Latitude').val(country.Latitude);
   console.log(">>>>" + country.Latitude);
});

I don't need a loop though since it's a single set of values. Is there another, cleaner way to format this and avoid the extra function? As you can see from my code above, I've tried this:

console.log(">>>>" + data.LatLng.Latitude);
$('#Latitude').val(data.LatLng.Latitude);

...and many other things and it always comes back undefined. Here is my StateList piece from the controller:

[HttpGet]
    public ActionResult StateList(int id)
    {
        var list = db.States.Where(d => d.CountryId == id).Select(d => new { Text = d.StateName, Value = d.StateId }).ToList();
        var latlng = db.Countries.Where(d => d.CountryId == id).Select(d => new { d.Latitude, d.Longitude });
        var result = new { List = list, LatLng = latlng };
        return Json(result, JsonRequestBehavior.AllowGet);
    }

I tried formatting the latlng data in this ActionResult (i.e. ToList, ToString, Lat = d.Latitude, etc etc), yet jquery doesn't seem to care as long as I put it in the loop.

All examples that I can find on the internet are for json lists which worked great on the state list section. But, I can't seem to find anything regarding a single json value. And it seems thus far, that you have to break the value into pieces so jquery can interpret it? Anyone know the trick to eliminate the loop?

Jasen
  • 14,030
  • 3
  • 51
  • 68
Sum None
  • 2,164
  • 3
  • 27
  • 32
  • 3
    Dump to console the json result and check the `LatLng`. It's probably an array so then adjust your query by adding `.Single()` or `.First()`. – Jasen Jun 12 '15 at 20:18
  • 1
    Try: `console.log(data.LatLng[0].Latitude);` – Hackerman Jun 12 '15 at 20:26
  • Thanks guys, I'm not sure if `data.LatLng[0].Latitude` was more of a troubleshooting step, but both of these actually work for what I'm trying to do. I think I was looking for the `.Single()` as it seems a little more clean/elegant. If it had been `ToSingle()`, I might have figured it out myself. It amazes me I can't find this stuff in google including how to dump everything to the console. Anyway... @Jasen If you want to write that up, I'll give you credit as the answer. Thanks. – Sum None Jun 13 '15 at 01:09

1 Answers1

0

It appears your LatLng query returns a collection instead of a single item. Therefore, your json result will be an array, forcing you to iterate also making data.LatLng.Latitude undefined.

You can adjust your query to return a single item instead of a collection with .Single(), .SingleOrDefault(), .First(), or .FirstOrDefault().

var latlng = db.Countries.Single(d => d.CountryId == id)
               .Select(d => new { d.Latitude, d.Longitude });

Then you can remove that extra $.each() loop to access the LatLng properties.

Community
  • 1
  • 1
Jasen
  • 14,030
  • 3
  • 51
  • 68
  • Interesting, VS is throwing an error when I put `Single` up front after `db.Countries` like that. It doesn't like the `Select` (no definition or extension method for select). However, if I do it like this: `var latlng = db.Countries.Where(d => d.CountryId == id).Select(d => new { d.Latitude, d.Longitude }).Single();` ... everything works as expected. – Sum None Jun 13 '15 at 03:36