34

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>

4 Answers 4

66

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.

Sign up to request clarification or add additional context in comments.

2 Comments

@PankajParkar are you able to provide an example of the latter solution for providing a controller? I am having a hard time getting that to work. Here's my question that relates: stackoverflow.com/questions/35350463/…
I think below answer should help you..anyways i will look into that.
24

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;

        }]);
}());

1 Comment

Yes, I agree with you. Using separate controller will allow to manage the code properly.
2

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: '<'
}

Comments

-1

I got the below code working:

this.OpenModal = function() {
        var modalInstance = $uibModal.open({
            url: "/name?parameter=" + $scope.Object.ParamValue,
            templateUrl: 'views/module/page.html',
            controller: myController
        });
    }

1 Comment

you should include more information on how your answer solve the problem

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.