1

This is taken from Jason Watmore's tutorial on building an Angular.js modal window: http://jasonwatmore.com/post/2016/07/13/angularjs-custom-modal-example-tutorial

This is a separate file called index.controller.js that houses just this controller.

(function () {

    angular
        .module('app')
        .controller('Home.IndexController', Controller);

    function Controller(ModalService) {
        var vm = this;

        vm.openModal = openModal;
        vm.closeModal = closeModal;

        function openModal(id){
            ModalService.Open(id);
        }

        function closeModal(id){
            ModalService.Close(id);
        }
    }

})();

I have tried porting this to my app.js file within a controller called screeningsController, like this:

app.controller('screeningsController', ['$scope', '$log', function($scope, $log){

    // this is a test function
    $scope.popup = function() {

    // assign a message to the $scope
    $scope.message = 'Hello World!';

    // use the $log service to output the message in a console
    $log.log($scope.message);

    };

    // this is the function that was ported over
    function Controller(ModalService) {
        var vm = this;

        vm.openModal = openModal;
        vm.closeModal = closeModal;

        function openModal(id){
            ModalService.Open(id);
        }

        function closeModal(id){
            ModalService.Close(id);
        }
    }

}]);

The first function is just a test to see if the controller is able to be reached and working (it is). The second function "Controller" does not work. Dreamweaver throws the error, "'Controller' is defined but never used." This doesn't throw any errors in the browser console, but the function doesn't do anything.

Here is a section of my screenings partial screenings.php, where these functions are called:

...
while ($row = mysqli_fetch_array($result)){
        echo "<div id='img_div' ng-click='popup()'>";
            echo "<img id='img_screenings' class='modal_img' ng-click=\"vm.openModal('custom-modal-1')\" src='images/".$row['image']."' >";
...

The first echo houses the test function, and the second echo houses the other function. This is exactly how that function is called in the tutorial code. For reference:

<img class="picture" ng-click="vm.openModal('custom-modal-1')" src="picture.png">

Given all that, is there any indication as to why the second function is not working in my code?

rpivovar
  • 3,150
  • 13
  • 41
  • 79

1 Answers1

1

The original file used the Controller function as the actual controller:

.controller('Home.IndexController', Controller);

But you created your own controller, and then moved the entire Controller function inside your own. You just need to take the functions:

app.controller('screeningsController', ['$scope', '$log', "ModalService", function($scope, $log, ModalService){

    // this is a test function
    $scope.popup = function() {

    // assign a message to the $scope
    $scope.message = 'Hello World!';

    // use the $log service to output the message in a console
    $log.log($scope.message);

    };

    var vm = this;

    vm.openModal = openModal;
    vm.closeModal = closeModal;

    function openModal(id){
        ModalService.Open(id);
    }

    function closeModal(id){
        ModalService.Close(id);
    }

}]);

Edit: Now you are binding to your controller in 2 different ways ($scope and this). You might want to just pick one of those to avoid confusion.

Frank Modica
  • 10,238
  • 3
  • 23
  • 39
  • Thanks, it seems to not throw the error in Dreamweaver anymore. Still not firing the function though. I guess the problem is elsewhere. – rpivovar May 12 '17 at 22:11
  • 1
    How are you connecting the template to this controller? If you're using `ng-controller`, you need the `controllerAs` syntax: `ng-controller="screeningsController as vm"`. If you're using the router or a directive, you need a `controllerAs` property. – Frank Modica May 12 '17 at 22:15
  • Are `$scope` and `this` basically the same thing? – rpivovar May 13 '17 at 00:59
  • If there is no `controllerAs` property, would that account for the test function firing and the other one not firing? – rpivovar May 13 '17 at 01:02
  • I think this answers my first question: http://stackoverflow.com/questions/11605917/this-vs-scope-in-angularjs-controllers – rpivovar May 13 '17 at 01:05
  • 1
    Yes you need `controllerAs` somewhere to bind directly to `this` which is the instance of the controller. – Frank Modica May 13 '17 at 01:10
  • 1
    Or you can forget about `controllerAs` and attach your new functions to `$scope` instead of `vm`. In the template just remember to remove `vm.` – Frank Modica May 13 '17 at 01:26
  • As far as `controllerAs` vs `$scope`, is one preferred over the other? Does one make more sense here than the other? – rpivovar May 13 '17 at 01:26
  • I see - this is starting to make a lot more sense now. I guess the `vm` is a variable for `this` – rpivovar May 13 '17 at 01:27
  • So I could sub `$scope` in place of `vm` and just drop the `vm` declaration altogether? – rpivovar May 13 '17 at 01:28
  • 1
    It's often preference, but `controllerAs` is nice because you don't have to inject `$scope` into your controller unless you need it for some other reason, you clearly see `vm.` in your templates, you don't encounter some edge case issues involving data-binding and the prototypal inheritance of scopes, etc. There are tons of resources you can check out on the web. – Frank Modica May 13 '17 at 01:32
  • 1
    Yep! I'd say read up on the differences and just pick one. Mixing them up can get confusing. – Frank Modica May 13 '17 at 01:33
  • In the tutorial code, he has this: `ng-click="vm.openModal('custom-modal-1')"` ..that doesn't look like a `controllerAs` call, though? – rpivovar May 13 '17 at 01:36
  • 1
    Somewhere in the tutorial there must be `controllerAs: "vm"` – Frank Modica May 13 '17 at 01:41
  • Ah I see it. Thanks. – rpivovar May 13 '17 at 01:44