-1

I have a button on my page that modifies the model (adds a new object).

I was hoping I could do it within the HTML, simply by pushing a new object onto the array, but it looks like I may need to call the controler to do it. For some reason though it can't find the function in my controller.

Here's my button:

<button ng-click="addCarton()">Add a carton</button>

Here's one of the (several) controllers on this page:

myController.$inject = ['$http', '$uibModal', 'cart'];

function myController($http, $uibModal, cart) {
    var vm = this;

    vm.addCarton = function () {
        console.log("carton added!");
    });

This does nothing at all. No errors, just the button does nothing. I had no choice but to add the $scope dependency. This works:

myController.$inject = ['$http', '$uibModal', 'cart', '$scope'];

function myController($http, $uibModal, cart, $scope) {
    var vm = this;

    $scope.addCarton = function () {
        console.log("carton added!");
   });

So, why bother with vm=this if I can't use it?

--

I should mention there are other click events on the page, but I don't have any idea how they're operating:

<button type="button" ng-click="summaryModalVm.cancel()">Cancel</button>

function myController($http, $uibModal, cart, $scope) {

    vm.dimensionsChoose = function (size) {
            $http.post('/api/shipping/estimate', cart).then(function(response) {
                var modalInstance = $uibModal.open({
                    controllerAs: 'summaryModalVm',

[ UPDATE ]

My router:

            .state('layout.cart', {
                url: '/cart',
                templateUrl: '/Content/js/apps/store/views/cart.html',
                controller: 'cartController',
                controllerAs: 'cartVm',
                data: { pageTitle: 'Cart' }
            })

My 2nd try at a button:

            <button ng-click="cartVm.addCarton()" type="button">Add a carton</button>

My 2nd try at controller:

function cartController($http, $uibModal, Cart, CartObservable) {
    var vm = this;

    vm.addCarton = function () {
        console.log(":)");
    };
DaveC426913
  • 2,012
  • 6
  • 35
  • 63
  • I found a similar question that maybe can help you, the link is [here](http://stackoverflow.com/questions/11605917/this-vs-scope-in-angularjs-controllers) – Dlanor Jun 08 '16 at 19:51
  • The other click events on the page work because they are properly using the **Controller as** syntax and dot notation for referencing the controller functions. See my answer for how to get your `addCarton` function working. – Lex Jun 08 '16 at 19:54

3 Answers3

0

You don't show how you are referencing your controller in HTML, but in order for the first option (the one without $scope) to work, you need to use:

ng-controller = "myController as ctrl"

And then to call addCarton you use:

<button ng-click="ctrl.addCarton()">Add a carton</button>
Lex
  • 6,758
  • 2
  • 27
  • 42
  • I don't know how this guy's implemented this but there's no controller on this page - presumably it's a snippet or template. When I inspect the code, the controller that is the parent of this section is all the way up to AppController. I'm sure that's too high up the hierarchy. – DaveC426913 Jun 08 '16 at 20:01
  • From the snippet you provided it appears that it is being displayed using an angular-ui bootstrap modal and the controller is declared in the `controllerAs` option setting. – Lex Jun 08 '16 at 20:03
  • In the router? .state('layout.cart', { url: '/cart', templateUrl: '/Content/js/apps/store/views/cart.html', controller: 'cartController', controllerAs: 'cartVm', data: { pageTitle: 'Cart' } }) – DaveC426913 Jun 08 '16 at 20:04
  • Yep, there you go. So use `cartVm.addCarton()` and it should call your controller method. – Lex Jun 08 '16 at 20:12
  • I've edited the psot to incldue my router with options, and my 2nd attemtp at the button. No joy. – DaveC426913 Jun 08 '16 at 20:12
  • Based on what you have provided that should be working. – Lex Jun 08 '16 at 20:15
  • Is there a reverse-engineering way of telling what a control's scope is - instead of guessing? – DaveC426913 Jun 08 '16 at 20:19
  • Thanks Lex and @Luger for your prompt help. – DaveC426913 Jun 08 '16 at 21:22
  • I am not aware of a way to determine the controller or scope that something is running under besides tracing it through the code. That doesn't mean something doesn't exist (maybe search for "controllerprovider"), but simply that I don't know what it is. – Lex Jun 08 '16 at 21:26
0

Change <button ng-click="addCarton()">Add a carton</button> to <button ng-click="vm.addCarton()">Add a carton</button> . If that's button is within scope of controller, then it would work.

Luger
  • 2,090
  • 1
  • 13
  • 11
0

OK, I found the scope the button is within.

I don't understand it at all.

OK, it looks like he's defining the controller for the modal within the yes result of a preceding modal's yes response.

(see my inline comments: // ****)

(function() {
    'use strict';

    angular
        .module('WizmoApp')

        .controller('cartController', cartController)
        .controller('masterCartonModalInstanceController', masterCartonModalInstanceController)
        .controller('summaryModalInstanceController', summaryModalInstanceController)
        .controller('dimensionsModalInstanceController', dimensionsModalInstanceController)
        .controller('cartModalInstanceController', cartModalInstanceController);

    cartController.$inject = ['$http', '$stateParams', '$location', '$uibModal', '$log', 'toastr', 'DTOptionsBuilder', 'DTColumnDefBuilder', 'Cart', 'CartObservable'];

    function cartController($http, $stateParams, $location, $uibModal, $log, toastr, DTOptionsBuilder, DTColumnDefBuilder, Cart, CartObservable) {
    }

    // flow:
    // open masterCarton question
    //
    // if yes, open dimensions modal, get dimensions, add purolator label to cart, open cart summary
    // if no, go straight to cart summary
    //
    // open credit card modal
    masterCartonModalInstanceController.$inject = ['$uibModal', '$uibModalInstance', 'cart'];
    function masterCartonModalInstanceController($uibModal, $uibModalInstance, cart) {
        var vm = this;


        vm.yes = function(size) {

            var modalInstance = $uibModal.open({
                templateUrl: 'dimensionsModalContent',
// **** this seems to be the creation of the controller ****
// **** for the next modal ****
                controller: 'dimensionsModalInstanceController',
                controllerAs: 'dimensionsModalVm',
                size: size,
                resolve: {
                    cart: function() {
                        return cart;
                    },
                    masterCarton: function() {
                        return vm.masterCarton;
                    }
                }
            });
        };

        vm.no = function(size) {
        };
    }

    dimensionsModalInstanceController.$inject = ['$http', '$uibModal', '$uibModalInstance', 'toastr', 'cart', 'masterCarton', 'CartObservable'];
    function dimensionsModalInstanceController($http, $uibModal, $uibModalInstance, toastr, cart, masterCarton, CartObservable) {
        var vm = this;

        vm.addCarton = function () {
            console.log(":)");
// **** the code I'm trying to activate ****
        };

    }

    summaryModalInstanceController.$inject = ['$uibModal', '$uibModalInstance', 'cart', 'masterCarton'];
    function summaryModalInstanceController($uibModal, $uibModalInstance, cart, masterCarton) {
    }

    cartModalInstanceController.$inject = ['$http', '$state', '$uibModalInstance', 'toastr', 'cart', 'masterCarton', 'shippingLabelService'];
    function cartModalInstanceController($http, $state, $uibModalInstance, toastr, cart, masterCarton, shippingLabelService) {
    }
})();
DaveC426913
  • 2,012
  • 6
  • 35
  • 63