7
votes

I have problem with an angular modal service

My app.js includes:

angular.module('myApp', ['myApp.test', 'ui.bootstrap','smart-table''angularModalService','ngRoute','myApp.productInsert',...

test.js:

    'use strict';

angular.module('myApp.test', ['angularModalService'])



 .controller('ComplexController', [
  '$scope', '$element', 'title', 'close', 
  function($scope, $element, title, close) {

  $scope.name = null;
  $scope.age = null;
  $scope.title = title;

  //  This close function doesn't need to use jQuery or bootstrap, because
  //  the button has the 'data-dismiss' attribute.
  $scope.close = function() {
      close({
      name: $scope.name,
      age: $scope.age
    }, 500); // close, but give 500ms for bootstrap to animate
  };

  //  This cancel function must use the bootstrap, 'modal' function because
  //  the doesn't have the 'data-dismiss' attribute.
  $scope.cancel = function() {

    //  Manually hide the modal.
    $element.modal('hide');

    //  Now call close, returning control to the caller.
    close({
      name: $scope.name,
      age: $scope.age
    }, 500); // close, but give 500ms for bootstrap to animate
  };

}]);

And then test.html

<div class="modal fade">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" ng-click="close()" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title">{{title}}</h4>
      </div>
      <div class="modal-body">
        <p>Here's a more complex modal, it contains a form, data is passed to the controller 
         and data is returned from the modal.</p>

        <form class="form-horizontal" role="form">
          <div class="form-group">
            <label for="name" class="col-sm-2 control-label">Name</label>
            <div class="col-sm-10">
              <input type="text" class="form-control" id="name" placeholder="Your Name" ng-model="name">
            </div>
          </div>
          <div class="form-group">
            <label for="age" class="col-sm-2 control-label">Age</label>
            <div class="col-sm-10">
              <input type="number" class="form-control" id="inputPassword3" placeholder="Age" ng-model="age">
            </div>
          </div>
        </form>

      </div>
      <div class="modal-footer">
        <button type="button" ng-click="close()" class="btn btn-primary" data-dismiss="modal">OK</button>
        <button type="button" ng-click="cancel()" class="btn">Cancel</button>
      </div>
    </div>
  </div>
</div>

And the main page that opens modal windows

'use strict';

angular.module('myApp.ricetta2', ['ngRoute', 'angularModalService','ui.bootstrap'])

        .config(['$routeProvider', function($routeProvider) {
                $routeProvider.when('/ricetta2', {
                    templateUrl: 'views/ricetta/ricetta2.html',
                    controller: 'CartForm'
                });
            }])

        .controller('CartForm', ['$scope','ModalService', function($scope, ModalService) {
                $scope.invoice = {
                    items: [{
                            qty: 10,
                            description: 'Pomodori',
                            cost: 'Kg'}, {
                            qty: 10,
                            description: 'Olio',
                            cost: 'litri'}, {
                            qty: 4,
                            description: 'Pasta',
                            cost: 'Kg'}]
                };

                $scope.addItem = function() {
                    $scope.invoice.items.push({
                        qty: 1,
                        description: '',
                        cost: ''
                    });
                },
                        $scope.removeItem = function(index) {
                            $scope.invoice.items.splice(index, 1);

                        },
                        $scope.total = function() {
                            var total = 0;
                            angular.forEach($scope.invoice.items, function(item) {
                                total += item.qty * item.cost;
                            });

                            return total;
                        };

                $scope.items = ['item1', 'item2', 'item3'];
                $scope.productList = [];



              $scope.showComplex = function() {

                    ModalService.showModal({
                        templateUrl: "views/test/test.html",
                        controller: "ComplexController",
                        inputs: {
                            title: "A More Complex Example"
                        }
                    }).then(function(modal) {
                        modal.element.modal();
                        modal.close.then(function(result) {
                            $scope.complexResult = "Name: " + result.name + ", age: " + result.age;
                        });
                    });

                };


            }]);

When I try to open Modal windows I have always an error on the page:

TypeError: modal.element.modal is not a function at ricetta2.js:60 at processQueue (angular.js:13248) at angular.js:13264 at Scope.$get.Scope.$eval (angular.js:14466) at Scope.$get.Scope.$digest (angular.js:14282) at Scope.$get.Scope.$apply (angular.js:14571) at done (angular.js:9698) at completeRequest (angular.js:9888) at XMLHttpRequest.requestLoaded (angular.js:9829)(anonymous function) @ angular.js:11655$get @ angular.js:8596processQueue @ angular.js:13256(anonymous function) @ angular.js:13264$get.Scope.$eval @ angular.js:14466$get.Scope.$digest @ angular.js:14282$get.Scope.$apply @ angular.js:14571done @ angular.js:9698completeRequest @ angular.js:9888requestLoaded @ angular.js:9829

I have all the resources linked on the index.html:

<link rel="stylesheet"href="bower_components/bootstrap/dist/css/bootstrap.css">
<script src="bower_components/angular/angular.js"></script>
        <script src="bower_components/jquery/dist/jquery.min.js"></script>
        <script src="bower_components/angular-bootstrap/ui-bootstrap.min.js"></script>
        <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
        <script src="bower_components/angular-modal-service/dst/angular-modal-service.js"></script>
        <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>

I'm very new to angularjs and I don't know the solution!!

Thanks all

6
In your app.js you are missing a comma between two of the dependencies smart-table''angularModalService',Aaron
in my code comma is present, it is not present only in stackoverflow section, so this is not the error .Alberto
@Andrea I think you have to add bootstrap.js or bootstrap/modal.js as depencency.ajahongir
look at bottom of the page "I'm using a Bootstrap Modal and the dialog doesn't show up" section - github.com/dwmkerr/angular-modal-service also: github.com/dwmkerr/angular-modal-service/issues/14ajahongir
I have bootstrap.js loading before angular and still get "TypeError: modal.element.modal is not a function" I can even click on it in the HTML and it opens, so I know bootstrap.js is loading. Maybe its a version disharmony?FlavorScape

6 Answers

16
votes

I had same problem. Interchanging the script tags locations solved my problem. At first I had script tags in this sequence

    <script type="text/javascript" src="js/angular.min.js"></script>
    <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
    <script type="text/javascript" src="js/bootstrap.js"></script>

Then I changed it to this.

    <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
    <script type="text/javascript" src="js/angular.min.js"></script>
    <script type="text/javascript" src="js/bootstrap.js"></script>   

Many times these things happen. Conflicts occur because of loading AngularJS before jQuery.

4
votes

Hi here is the correct detailed solution from https://www.npmjs.com/package/angular-modal-service

I'm using a Bootstrap Modal and the dialog doesn't show up

Code is entered exactly as shown the example but when the showAModal() function fires the modal template html is appended to the body while the console outputs:

TypeError: undefined is not a function Pointing to the code: modal.element.modal();. This occurs if you are using a Bootstap modal but have not included the Bootstrap JavaScript. The recommendation is to include the modal JavaScript before AngularJS.

2
votes

The documentation is incorrect. I'm submitting a PR for the examples.

In the meantime change to this:

.then( function(modal)
 {
     modal.element.show();
 });
1
votes

Yes you just need to put in order your external js apis first -> jQuery.js second -> Boostrap.js -> Angular.js like this

<script src="../../resources/js/jquery.js"  th:src="@{/resources/js/jquery.js}"></script>   
<script src="../../resources/js/bootstrap.js"  th:src="@{/resources/js/bootstrap.js}"></script>
<script src="../../resources/js/angular.js"  th:src="@{/resources/js/angular.js}"></script>
<script src="../../resources/js/angular-modal-service.js" th:src="@{/resources/js/angular-modal-service.js}" ></script>

Sorry for this tag "th:src" I am using thymeleaf :)

1
votes

angularModalService requires bootstrap js You already loaded bootstrap.js and jquery.js You have to load jquery.js first and then bootstarp.js and then angular.js . So your resources linked in index.html should be..

<link rel="stylesheet"href="bower_components/bootstrap/dist/css/bootstrap.css">
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap.min.js"></script>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<script src="bower_components/angular-modal-service/dist/angular-modal-service.js"></script>
-2
votes

Now i faced similar issue and it was fixed with adding below script files at the top of html. src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js" src = "http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.0/bootstrap.min.js"