2

scope is undefined after callback from $uibModal

I have a directive (Angularjs) that has a controller, from there I am calling an uibModal where I want to modify some details of an object where I clicked. With the modal I am sending two parameters and a callback, everything seems to be ok but when angular go back to the callback function the scope of the controller (not the modal controller) is undefined, actually everything is undefined, how can I comunicate these two controllers, so when the user update something in the modal I can update it in the other controller.

modal.controller

(function () {
    "use strict";

    angular
        .module("app.users")
        .controller("editVitalCtrl", editVitalCtrl);

    editVitalCtrl.$inject = ["items"];
    function editVitalCtrl(items) {

        var vm = this;
        vm.modalTitle = "Edit " + items.vital.title;
        vm.vital = items.vital;

        vm.clickCancelModal = function () {
            vm.$close();
        }

        vm.clickSaveModal = function () {
            $scope.$result(items.saveCallback($scope.vital));
        }

    }
})();

directiveThatOpenTheModal.directive.js

(function () {
    "use strict";

    angular
        .module("app.users")
        .directive("directiveThatOpenTheModal", [
            function () {
                return {
                    restrict: "E",
                    scope: {
                        columnConfig: "=columnConfig",
                        partnerId: "=partnerId"
                    },
                    link: {
                        pre: function (scope) {

                        }
                    },
                    controller: ["$http", "$scope", "$uibModal",
                        function ($http, $scope, $uibModal) {
                            $scope.vitalList = [];


                            if ($scope.partnerId) {

                                var params = {
                                    bankId: Number.isInteger($scope.partnerId) ? $scope.partnerId : -1
                                };

                                getColumnConfiguration(params, $http).success(function (data) {
                                    $scope.vitalList = data.columns;
                                });
                            }

                            $scope.removeVital = function (vital) {
                                removeVital(vital);
                            }

                            function callback(vital) {
                                // Code here in callback, after code get in here everythings is undefined
                            }

                            $scope.editVital = function (vital) {

                                $scope.modal = $uibModal.open({
                                    animation: true,
                                    windowClass: 'modal-add-cont modal-alerts',
                                    templateUrl: '/controller/view',
                                    controller: 'modalCtrl',
                                    resolve: {
                                        items: function () {
                                            return {
                                                vital: vital,
                                                saveCallback: callback,
                                                partnerId: $scope.partnerId,
                                                scope: $scope
                                            }
                                        }
                                    },
                                    size: 'lg'
                                });
                            }


                            function removeVital(vital) {
                                var index = $scope.vitalList.indexOf(vital);
                                $scope.vitalList.splice(index, 1);
                            }
                        }],
                    templateUrl: '/route/Configuration'
                };
            }]);
    function getColumnConfiguration(params, $http) {
        var url = "/someroute/somemethod";
        return $http.get(url, { params: params });
    }
})();
Community
  • 1
  • 1
Dayán Ruiz
  • 611
  • 1
  • 9
  • 22
  • I typically like to use $broadcast, e.g. event listeners in this situation. – Tobiah Rex Jun 05 '18 at 21:43
  • What version of AngularJS are you using? The `$http.success` method has been [deprecated and removed from V1.6](https://stackoverflow.com/questions/35329384/why-are-angular-http-success-error-methods-deprecated-removed-from-v1-6/35331339#35331339). – georgeawg Jun 05 '18 at 23:39
  • It is not wise to use callbacks from a modal. The recommended practice is to resolve the promise that the modal returns. – georgeawg Jun 05 '18 at 23:44
  • The modal controller doesn't inject $scope, so of course it is undefined. – georgeawg Jun 05 '18 at 23:58
  • @georgeawg can you please give me an alternative or something? – Dayán Ruiz Jun 06 '18 at 12:09
  • Modal dialogs can *double error rates*, increase time to task completion, and are near-universally despised by users. Alternate means of notification are often available and should be utilized wherever possible and appropriate. For more information, see [What research is there suggesting modal dialogs are disruptive?](https://ux.stackexchange.com/questions/12637/what-research-is-there-suggesting-modal-dialogs-are-disruptive) – georgeawg Jun 06 '18 at 13:27

1 Answers1

2

can you please give me an alternative or something?

It is not wise to use callbacks from a modal. The recommended practice is to resolve the promise that the modal returns.

Modal controller

app.controller("modalCtrl", function(items) {

    var vm = this;
    vm.modalTitle = "Edit " + items.vital.title;
    vm.vital = items.vital;

    vm.clickCancelModal = function () {
        vm.$dismiss('cancel');
    }

    vm.clickSaveModal = function () {
        vm.$close(vm.vital));
    }

})

Open modal

$scope.editVital = function (vital) {

    $scope.modal = $uibModal.open({
        animation: true,
        windowClass: 'modal-add-cont modal-alerts',
        templateUrl: '/controller/view',
        controller: 'modalCtrl',
        resolve: {
            items: function () {
                return {
                    vital: vital,
                    ̶s̶a̶v̶e̶C̶a̶l̶l̶b̶a̶c̶k̶:̶ ̶c̶a̶l̶l̶b̶a̶c̶k̶,̶
                    partnerId: $scope.partnerId,
                    scope: $scope
                }
            }
        },
        size: 'lg'
    });

    var promise = $scope.modal.result;

    promise.then(function(result) {
        console.log("Save", result);
    }).catch(function(reason) {
        console.log("Cancel", reason);
    });
}

For more information, see AngularUI Bootstrap ui.bootstrap.modal API Reference


Modal dialogs can double error rates, increase time to task completion, and are near-universally despised by users. Alternate means of notification are often available and should be utilized wherever possible and appropriate.

For more information, see What research is there suggesting modal dialogs are disruptive?

georgeawg
  • 48,608
  • 13
  • 72
  • 95