{"id":1783,"date":"2022-08-30T15:19:24","date_gmt":"2022-08-30T15:19:24","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/12\/02\/inject-a-controller-into-a-running-angular-app-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:19:24","modified_gmt":"2022-08-30T15:19:24","slug":"inject-a-controller-into-a-running-angular-app-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/inject-a-controller-into-a-running-angular-app-collection-of-common-programming-errors\/","title":{"rendered":"Inject a controller into a running Angular app-Collection of common programming errors"},"content":{"rendered":"<p>I&#8217;ve written some simple code to allow for bootstrap modals to work with angular in that it loads a link into a modal when clicked. Now the links in question have their own angular controllers which are included in their source. When the modal is being loaded I first use jquery to load all it&#8217;s dependant scripts and then have Angular compile the modal so that it is &#8220;aware&#8221; of it. However it seems that despite the fact that I define the controller on-demand as the modal is loaded, Angular will not be &#8220;aware&#8221; of it and throws an error (Uncaught Error: Argument &#8216;ControllerName&#8217; is not a function, got undefined).<\/p>\n<p>Is there a way for me to tell Angular to recognize the new controller I&#8217;ve added at run-time?<\/p>\n<p>Here&#8217;s the modal code I&#8217;m using fwiw (prototype code):<\/p>\n<pre><code>var directivesModule = angular.module('modal.directives', []);\ndirectivesModule.directive(\"modal\", function(ModalService) {\n    return function($scope, elem, attrs) {\n            elem.on(\"click\", function(e) {\n                e.preventDefault();\n                var url = $(this).attr('href');\n\n                ModalService.load(url, $scope);\n            });\n    };\n});\n\nvar servicesModule = angular.module('modal.service', []);\nservicesModule.factory('ModalService', function ($http, $compile, $rootScope)\n{\n    var ModalService = {};\n\n    ModalService.load = function(url, scope)\n    {\n        if ($('.modal[id=\"'+url+'\"]').length &gt; 0)\n        {\n            ModalService.show($('.modal[id=\"'+url+'\"]'), scope);\n            return;\n        }\n\n        $http.get(url).success(function (data) {\n            var _data = $(data);\n            if (_data.find(\".modal-body\").length == 0) {\n                var _data =  $(''\n                      + 'x'\n                      + '<\/code><\/pre>\n<h3><code>'+_data.find(\".title.hidden\").text()+'<\/code><\/h3>\n<pre>'\n                      + ''+data+''\n                      + ''\n                      + 'Close');\n            }\n\n            var _scripts = [];\n            var scripts = _data.find(\"script\");\n            if (scripts.length &gt; 0)\n            {\n                scripts.each(function()\n                {\n                    var elem = $(this);\n                    if (elem.attr(\"src\"))\n                    {\n                        _scripts.push(elem.attr(\"src\"));\n                        elem.remove();\n                    }\n                });\n            }\n\n            ModalService.elem = $('');\n            ModalService.elem.append(_data);\n            ModalService.elem.appendTo(\"body\");\n\n            if (scripts.length &gt; 0)\n            {\n                $.getScript(_scripts, ModalService.show.bind(this, ModalService.elem, scope));\n            }\n            else\n            {\n                ModalService.show(ModalService.elem, scope);\n            }\n        });\n    };\n\n    ModalService.show = function(elem, scope)\n    {\n        $rootScope.$broadcast('$routeChangeSuccess');\n\n        $compile(elem)(scope);\n        elem.modal();\n\n        elem.find(\".btn-close\").click(function() {\n            elem.modal(\"hide\");\n            setTimeout(function() { elem.remove(); }, 500);\n        });\n    };\n\n    return ModalService;\n});\n<\/pre>\n<ol>\n<li>\n<p><code>Yes, it is possible, and all needed utilities are already included in angular. I cannot write ready code, but here is something that will give you an idea:<\/code><\/p>\n<ol>\n<li>\n<p><code>Load your HTML code, probably right into DOM -- something like <code>$('#myDiv').load('dialog.html')<\/code>. Do not bind controllers with <code>ng-controller<\/code>! Save a reference to DOM node (let's call it <code>element<\/code>).<\/code><\/p>\n<\/li>\n<li>\n<p>Load your controller &#8212; probably with head.js or whatever suits your situation best. Save a reference to controller function (<code>controller<\/code> is a good name). You don&#8217;t need to register it in your angular app, just a plain, global function. Reference any required services and scope as usual:<\/p>\n<\/li>\n<\/ol>\n<pre><code>function MyCtrl($scope, $resource, $http, $whatever, YourOwnService) {\n    $scope.hello = 'world';\n}\n<\/code><\/pre>\n<pre><code>function ($compile, $rootScope, $inject) {\n    var element = angular.element('#myDiv'),\n        controller = MyCtrl;\n\n    \/\/ We need new scope:\n    var $scope = $rootScope.$new(true);\n\n    \/\/ Compile our loaded DOM snippet and bind it to scope:\n    $compile(element)($scope);\n\n    $inject.invoke(controller, {\n        $scope:$scope \/\/ you can add any other locals required by your controller\n    });\n}\n<\/code><\/pre>\n<p>I cannot guarantee this code works as is, but it describes technique I&#8217;ve used couple of weeks ago. But I must warn you that this will not allow you to dynamically add AngularJS dependencies: your app should include all possible modules added before bootstrapping app.<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-12-02 01:31:00. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve written some simple code to allow for bootstrap modals to work with angular in that it loads a link into a modal when clicked. Now the links in question have their own angular controllers which are included in their source. When the modal is being loaded I first use jquery to load all it&#8217;s [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1783","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1783","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=1783"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1783\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=1783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=1783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=1783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}