Below is part of the Angular controller I use to populate three cascading lists of address data, with the last being a BootStrap Tab Page widget. I have only tested on Chrome and Edge so far, with similar results.
public class AreaController : BaseController
{
private readonly AreaClient _areaClient = new AreaClient(UserHelper.CurrentUser);
private readonly AgentClient _agentClient = new AgentClient();
[HttpPost]
public JsonResult ProvincesJson()
{
return Json(_areaClient.GetProvinces().ToList());
}
[HttpPost]
public JsonResult AreasJson(int provinceId)
{
var model = _areaClient.GetAreas(provinceId).ToList();
return Json(model);
}
[HttpGet]
public JsonResult SuburbsJson(int agentId, int areaId)
{
var allBurbs = _areaClient.GetSuburbs(areaId).ToList();
var agentBurbIds = _agentClient.GetAgentSuburbs(agentId).Select(ab => ab.SuburbId).ToList();
var model = allBurbs.Select(burb => new CheckListItemModel { Id = burb.SuburbId, Label = burb.SuburbName, IsChecked = agentBurbIds.Contains(burb.SuburbId) }).ToList();
return Json(model);
}
}
ProvincesJson
and AreasJson
work perfectly for this partial view:
<div id="areas-and-suburbs" ng-controller="areasCtrl">
<div class="form-group">
<select id="ProvinceId" ng-model="geo.provinces.selectedId" ng-change="geo.getAreas(agentId, geo.provinces.selectedId)" class="form-control">
<option ng-repeat="item in geo.provinces" ng-value="{{item.provinceId}}" class=".area-option">{{item.provinceName}}</option>
</select>
</div>
<div class="form-group">
<select id="AreaId" ng-model="geo.areas.selectedId" ng-change="geo.setSuburbs(geo.areas.selectedId)" class="form-control">
<option ng-repeat="item in geo.areas" ng-value="{{item.areaId}}" class=".area-option">{{item.areaName}}</option>
</select>
</div>
<div class="form-group">
<div id="area-suburbs-partial">
@Html.Partial("_Suburbs")
</div>
</div>
</div>
The inner partial, _Suburbs
looks like this:
$scope.geo.getSuburbs = function(agentId, areaId) {
var geoUrl = "\/Area/SuburbsJson";
$http.post(geoUrl, { areaId: 3, agentId: 1 }, postOptions)
.then(function(response) {
var model = angular.fromJson(response.data);
$scope.agentSuburbs = model.$values;
_.defer(function() {
$scope.$apply();
});
},
function error(response) {
alert("Ajax error [getSuburbs]: " + response.responseText);
});
};
Yet when the outer parial renders __Suburbs
, which calls geo.setSuburbs
, I get "localhost refused to connect" error in Chrome. Everything in this project is same domain, just one project, and the Provinces and Areas dropdowns cascade properly, but when I select a new Area, to trigger fetching suburbs for that area, I get the error.
I see very little difference between the three actions, so I really don't understand why a connection to the third is refused. I even removed the business logic from SuburbsJson
to return a simple array of int
, and called it directly from the browser, vs. from my Angular controller's Ajax logic, and I still got a refused connection.
What could be behind just this one controller action causing a refused connection?
BREAKING:
I was a touch dyslexic somewhere with the spelling of area
. Fixing that solved everything on that day.