2
votes

I am getting an unknown provider error when attempting to launch an angular bootstrap modal window from my app by clicking on an image. I launch the same type of modal successfully elsewhere in the app.

Here is a screenshot of the error in the debugger

Is there something wrong with my controller code below? I looked at several other unknown provider error posts on stack, and to my knowledge I'm doing things properly.

app.controller('ModalInstanceCtrl', function($scope, $modalInstance, items,
 removeVideoFromCart, removeLiteratureFromCart, productHasItems, cartItemHasVideos,
 cartItemHasLiterature, getCartMailToBody, cartMailtoLink, logSentItems) {

    $scope.items = items;

    $scope.ok = function() {
        $modalInstance.close($scope.test);
    };

    $scope.removeVideoFromCart = function (video, familyIndex, index) {
        removeVideoFromCart(video, familyIndex, index);
        $scope.cartMailtoLink = getCartMailToBody(); //update the mailto link body to remove video links
    }

    $scope.removeLiteratureFromCart = function (literature, familyIndex, index) {
        removeLiteratureFromCart(literature, familyIndex, index); 
        $scope.cartMailtoLink = getCartMailToBody(); //update the mailto link body to remove lit links
    }       

    $scope.cancel = function() {
        $modalInstance.dismiss('cancel');
    };

    $scope.productHasItems = function(index) {
        return productHasItems(index);
    }

    $scope.cartItemHasVideos = function(index) {
        return cartItemHasVideos(index);
    }

    $scope.cartItemHasLiterature = function (index) {
        return cartItemHasLiterature(index);
    }

    $scope.getCartMailToBody = function () {
        getCartMailToBody();
    }
    $scope.cartMailtoLink = getCartMailToBody();

    $scope.logSentItems = function () {
        logSentItems();
    }

});

Thank you very much for your time. Let me know if you need more information or if I am being unclear.

3
where is removeVideoFromCart declared? and what order are you loading the scripts in the HTML?Claies
where are you injecting your dependencies? if removeVideoFromCart is a service you have written then how are you calling it as a function?Ritt

3 Answers

1
votes

I'm going to assume that app points to a declaration of that module that is defined at the root of your app e.g. in app.js:

app = angular.module('app', []);

And that you're including each dependency within your index.html e.g. after any angular scripts and app.js

<script src="yourDependency.js"></script>

In terms of the controller code itself, you don't need to assign to $scope a property that contains a function that calls the removeVideoFromCart service within your 'ModalInstanceCtrl' controller, because then you will still need to call that wrapper function again (which it currently looks like you are not doing).

You can just call the method within the controller rather than wrap it in a function e.g.

$scope.removeVideoFromCart = removeVideoFromCart(video, familyIndex, index);

or just call the service e.g. if you don't need to bind the data to the UI like sending form data that on success just redirects elsewhere (although in your case it looks like you do want to bind the data to the UI):

removeVideoFromCart(video, familyIndex, index);

It's not clear from your code where the parameters for each service originate from. Are they within the items object? e.g.

var video, familyIndex, index
vm.items = items; 
   video = items.video;
   familyIndex = items.familyIndex;
   index = items.index;

In terms of style, I prefer not assigning the module instances to a variable and instead use the setter syntax (following [John Papa's] (https://github.com/johnpapa/angular-styleguide#modules) styleguide, but also included in Todd Motto's), like so:

angular
    .module('app')
    .controller('ModalInstanceCtrl', ModalInstanceCtrl);

ModalInstanceCtrl.$inject['your', 'dependencies', 'go', 'here']

function ModalInstanceCtrl(/*dependencies here as parameters e.g.*/, removeVideoFromCart) {

    var vm = this; // use in place of $scope and clarifies the context of the this keyword
    vm.items = items; 
    video = items.video;
    familyIndex = items.familyIndex;
    index = items.index;

    $scope.removeVideoFromCart = removeVideoFromCart(video, familyIndex, index);
    $scope.removeLiteratureFromCart = removeLiteratureFromCart(literature, familyIndex, index);
    //etc

});

NB: I would prefer a facade into all of those methods e.g. clearCartAndCloseModal('other', 'services') to hide all of the implementation details from the controller. This also makes it easier to create one controller per view that is in turn easier to test beacuse you have pushed all logic into the services. But I'm not clear from your code whether there is any relationship between each of the services.

0
votes

@Claies @ritesh I was typing a long edit with responses to the questions when I happened upon my solution. I had multiple functions that opened modal windows using ModalInstanceController. For example, here are two:

$scope.open = function(size) {
                var modalInstance = $modal.open({
                    templateUrl: 'myModalContent.html',
                    controller: 'ModalInstanceCtrl',
                    size: size,
                    resolve: {
                        items: function() {
                            return $scope.selectedVideo3;
                        }
                    }
                });

                modalInstance.result.then(function(selectedItem) {
                    $scope.selected = selectedItem;
                }, function() {
                    $log.info('Modal dismissed at: ' + new Date());
                });
        };

        $scope.openCart = function(size) {

            var modalInstance = $modal.open({
                templateUrl: 'myAttachmentModalContent.html',
                controller: 'ModalInstanceCtrl',
                size: size,
                resolve: {
                    items: function() {
                        return "";
                   },
                    removeVideoFromCart: function() {
                            return $scope.removeVideoFromCart;
                    },
                    removeLiteratureFromCart: function() {
                            return $scope.removeLiteratureFromCart;
                    },
                    productHasItems: function() {
                            return $scope.productHasItems;
                    },
                    cartItemHasVideos: function() {
                        return $scope.cartItemHasVideos;
                    },
                    cartItemHasLiterature: function() {
                        return $scope.cartItemHasLiterature;
                    },
                    getCartMailToBody: function() {
                        return $scope.getCartMailToBody
                    },
                    cartMailtoLink: function() {
                        return $scope.cartMailtoLink
                    },
                    logSentItems: function () {
                        return $scope.logSentItems;
                    }
                }
            });

            modalInstance.result.then(function(selectedItem) {
                $scope.selected = selectedItem;
            }, function() {
                $log.info('Modal dismissed at: ' + new Date());
            });
        };

I only use most of the dependencies for ModalInstanceController in the openCart function, so I didn't add all of the dependency function declarations to my other open methods (You can see in the resolve for the $scope.open method above I only declare items and no functions).

I needed to declare all of these functions like I did in $scope.openCart and it fixed my problem.

Thank you for reaching out.

0
votes

My case was UpperCase LowerCase problem in the injected service name.