Alberto
Alberto

Reputation: 123

Angular modal service error - TypeError: modal.element.modal is not a function

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

Upvotes: 7

Views: 21881

Answers (6)

user3583769
user3583769

Reputation: 1

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"

Upvotes: -2

Akshay S. Pate
Akshay S. Pate

Reputation: 311

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.

Upvotes: 17

Raj
Raj

Reputation: 489

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>

Upvotes: 2

arielduarte
arielduarte

Reputation: 536

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 :)

Upvotes: 1

CALVIN MASHISHI
CALVIN MASHISHI

Reputation: 41

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.

Upvotes: 4

FlavorScape
FlavorScape

Reputation: 14269

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

In the meantime change to this:

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

Upvotes: 2

Related Questions