0

I have the following Angular declarations, and get no complaints about JS syntax errors or anything like that:

App.js:

(function () {
    'use strict';

    var hookPointApp = angular.module("hookPointApp", []);
    hookPointApp.controller("agentCtrl", function ($scope, $http) {
        $scope.model = {};
        ...
    });
})();

suburbsCtrl:

(function () {
    'use strict';

    angular.module("hookPointApp").controller('suburbsCtrl', function ($scope, $http) {
        $scope.areas.url = "/Area/ProvinceAreas";
        $scope.areas.getOptions = function (provinceId) {
            var area = "{'provinceId': '" + provinceId + "'}";
            $.ajax({
                url: $scope.areas.url,
                type: "POST",
                data: area,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                async: false,
                cache: false,
                success: function (response) {
                    if ((response !== null) && (typeof response !== "undefined")) {
                        $scope.areas.options = response;
                    }
                },
                error: function (xmlHttp, textStatus, errorThrown) {
                    alert(errorThrown);
                }
            });
        };
        // TODO Get a proper provinceId somehow.
        $scope.areas.getOptions(1);
        ...
    });
})();

Then I have a repeater with options declared like:

<div ng-controller="suburbsCtrl">
    <div class="form-group">
        @Html.LabelFor(model => model.AreaId, new { @class = "control-label" })
        <select class="form-control" ng-model="areas.areaId" ng-change='areas.getOptions($("#province.val()"))'>
            <option> - Select an Area - </option>
            <option id="province" ng-repeat="item in areas.options" ng-value="{{item.Id}}">{{item.Label}}</option>
        </select>
    </div>
</div>

Yet getOptions isn't called when I change the select option, and breakpoints I put in the Chrome debugger, even on lines not in functions, execution doesn't stop there, e.g. $scope.areas.getOptions(1); which is for initializing a dropdown, is not in a function, but below the function declaration, so I want to declare the function then call it immediately afterwards. A breakpoint in the module file, on var hookPointApp = angular.module("hookPointApp", []); doesn't even work, yet some Angular functionality in the app still sometimes works.

The Angular (core and my own) files are, I think, correctly referenced at the bottom of the body element in Layout.cshtml:

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    <script src="~/Scripts/angular/angular.js"></script>
    <script src="~/Scripts/angular/angular-resource.min.js"></script>
    <script src="~/Scripts/App/App.js"></script>
    <script src="~/Scripts/App/suburbsCtrl.js"></script>
    @RenderSection("ViewScripts", required: false)
</body>

What could I be doing wrong?

ProfK
  • 49,207
  • 121
  • 399
  • 775
  • 1
    What is areas.options?Is it possible to show this array content? – brk May 23 '16 at 04:54
  • Just BTW, apparently Chrome has issues with breakpoints, so I am using the good old, dirty `debugger` statement, and the code is indeed running. Now I can more easily find the problem. – ProfK May 23 '16 at 05:34

3 Answers3

2

First, Instead of referencing your module through a variable, could you use the getter syntax for the module. I would also split module declaration and c controller definition into separate file. This is in line with John Papa's Angular Style Guide endorsed by the Angular team:

App.js

(function () {
'use strict';

angular.module("hookPointApp", []);    
})();

agentCtrl.js

(function () {
'use strict';


angular.module("hookPointApp").controller("agentCtrl", function ($scope, $http) {
    $scope.model = {};
   });
})();

Secondly, you should probably use $http service of Angular or another library for $http requests e.g Restangular. The issue you have is because you are probably using jQuery's ajax method which upon completion has no way of letting the angular digest loop of knowing that there is a response from the server unless you notify it through $scope.apply().

Note that in the Promise resolution we use the thenmethod of the promise and not success which has been deprecated. Read more here about $http and the deprecation notice.

Here is suburbsCtrl.js with the $http service.

(function () {
'use strict';

angular.module("hookPointApp").controller('suburbsCtrl', function ($scope, $http) {
    $scope.areas.url = "/Area/ProvinceAreas";
  $scope.areas.url = "/Area/ProvinceAreas";
$scope.areas.getOptions = function (provinceId) {
    $http.post($scope.areas.url, {
        provinceId: provinceId
    }).then(function(data){
        if (data) {
            $scope.areas.options = data;
        }
    }).catch(function(err){
      console.error(err);
    });
};
    // TODO Get a proper provinceId somehow.
    $scope.areas.getOptions(1);

});
})();

PS- The Angular documentation encourages using Angular's services and only using jQuery's methods when not available. I would recommend trying to use Angular without external jQuery dependency and use the inbuilt jqLite in Angular for those methods that you would use jQuery for.

Also look at these resources:

https://docs.angularjs.org/guide

"Thinking in AngularJS" if I have a jQuery background?

Community
  • 1
  • 1
Evans Dianga
  • 210
  • 2
  • 11
0

getOptions() is undefined.

define:

(function () {
    'use strict';

    angular.module("hookPointApp").controller('suburbsCtrl', function ($scope, $http) {
    ...
    // TODO Get a proper provinceId somehow.
    $scope.areas.getOptions(1);
    ...
    $scope.getOptions = function() {
        // on change select , call this
    };
});
})();
Huey Zhang
  • 131
  • 1
  • 9
  • No, it is defined, but quite long and I omitted it for brevity. That's what the ellipses (...) mean. I have added the function now. And don't you mean `$scope.areas.getOptions = function()`? – ProfK May 23 '16 at 05:04
  • angular.module("hookPointApp")? Are you sure not angular.module("hookPointApp", [])? – Huey Zhang May 23 '16 at 05:06
  • You don't need the module dependencies when just adding a function, only the function dependencies, which are non. You only need the empty dependency array when you first declare the module. – ProfK May 23 '16 at 05:19
0
  • angular.module("hookPointApp", []) (add bracket)
  • use angular http replace jquery ajax, because some time unable update dom.

Try it:

(function () {
'use strict';

angular.module("hookPointApp", []).controller('suburbsCtrl', function ($scope, $http) {
    $scope.areas.url = "/Area/ProvinceAreas";
    $scope.areas.getOptions = function (provinceId) {
        $http.post($scope.areas.url, {
            provinceId: provinceId
        }).success(function(data){
            if (data) {
                $scope.areas.options = data;
            }
        });
    };
    // TODO Get a proper provinceId somehow.
    $scope.areas.getOptions(1);
    ...
});
})();
Huey Zhang
  • 131
  • 1
  • 9