AngularJS passing data to bootstrap modal

65,920

Solution 1

I'd suggest you to pass the scope of your own controller instead of passing same controller again, by doing that you can remove the resolve also.

var modalInstance = $uibModal.open({
    templateUrl: 'myModalContent.html',
    scope: $scope, //passed current scope to the modal
    size: 'lg'
});

Otherwise you need to create a new controller and assign that controller for modal while opening it.

Solution 2

When you use resolve, the map is injected into the given controller.

I recommend that u use a different controller to handle the modal functionality (separation of concerns).

I also recommend to use dependency injection to support minification of the code. Step 5 on the Angular tutorial wil explain this.

A simplified example of the modal controller would be.

(function () {

    'use strict';

    var app = angular.module('App');

    app.controller('musicDetailController',

                ['$scope', '$uibModalInstance', 'items',
        function ($scope, $uibModalInstance, items) {

            $scope.items = items;

        }]);
}());

Solution 3

You cannot pass an object directly.

I've tried all the solutions above, but wasn't really satisfied. I've solved the issue by writing a simple parser that enables you to pass both strings and objects directly to the modal, through the provided resolve function.

app.controller('ModalController', ['$uibModal', '$scope', function ($uibModal, $scope) {

    // Initialize $modal
    var $modal = this;

    // Open component modal
    $modal.open = function (component, size, data) {

        // Init modal
        var modalInstance = $uibModal.open({
            ariaLabelledBy: 'modal-title',
            ariaDescribedBy: 'modal-body',
            component: component,
            size: size || 'md',
            resolve: parseResolve(data)
        });
    };

    // Parse the resolve object
    function parseResolve(data) {
        if (typeof data === 'string') {
            return {
                data: function() {
                    return data;
                }
            }
        }
        else if (typeof data === 'object') {
            var resolve = {};
            angular.forEach(data, function(value, key) {
                resolve[key] = function() {
                    return value;
                }
            })
            return resolve;
        }
    }

}]);

When usings strings

Template:

<button ng-click="$modal.open('modalSomething', 'md', 'value'">
    Click
</button>

Component:

bindings: {
    resolve: '@'
}

When using objects

Template:

<button ng-click="$modal.open('modalSomething', 'md', {key1: value1, key2: value2})">
    Click
</button>

Component:

bindings: {
    resolve: '<'
}
Share:
65,920
Stefano Vuerich
Author by

Stefano Vuerich

Updated on July 04, 2020

Comments

  • Stefano Vuerich
    Stefano Vuerich almost 4 years

    I think I'm missing something but cannot figure what.
    Basically I'm trying to pass an object to the modal like below, but instead of getting the passed object I gets null...so I think is a problem with the scope but I'm new in Angular and need some help.

    Controller

    app.controller("musicViewModel", function ($scope, $http, $location, $uibModal, $log) {
    
    $scope.selected = null;
    
    $scope.open = function (item) {
    
        $scope.selected = item;
    
        $log.info('Open' + $scope.selected); // get right passes object
    
        var modalInstance = $uibModal.open({
            templateUrl: 'myModalContent.html',
            controller: 'musicViewModel',
            size: 'lg',
            resolve: {
                items: function () {
                    return $scope.selected;
                }
            }
        });
    };
    
    $scope.toggleAnimation = function () {
        $scope.animationsEnabled = !$scope.animationsEnabled;
    };
    });
    

    View

    <div class="row" ng-controller="musicViewModel">
        <script type="text/ng-template" id="myModalContent.html">
            <div class="modal-header">
                <h3 class="modal-title">I'm a modal!</h3>
            </div>
            <div class="modal-body">
                <ul>
                    <li>
                        {{ selected }} // always gets null
                    </li>
                </ul>
            </div>
        </script>
    </div>