Directive decorator in config block never called - angularjs

I'm using angularJS 1.4.9 and ui bootstrap 1.0.3.
I would like to decor uibDatepicker directive but the decorator function is never executed and there is no error or warning message in the console.
See this plunker
var uib = angular.module('ui.bootstrap');
uib.config(function($provide) {
$provide.decorator('uibDatepickerDirective', function($delegate) {
alert('never logs this');
return $delegate;
});
var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('MainCtrl', function() {
var main = this;
main.welcome = 'hello you';
});
Thanks for your help

The decorator function is never executed because you never actually use this directive you are trying to decorate.
Decorator is going to be invoked only when the directive is requested by real element in template. This is because services and directives are lazily configured (providers) so provider will not be active unless the service or directive is requested.
Here is an example of it being called when you put directive tag in template. Try adding this line in your code:
<uib-datepicker ng-model="dt" class="well well-sm"></uib-datepicker>
Demo: http://plnkr.co/edit/p4Hcgz83wv9d1WOl6eGo?p=preview

Related

Access directive method from the angularjs service

I have method in directive here i need to access this method from angularjs service.
For Example:
Service,
angular.module('myServiceModule', []).controller('MyController', ['$scope','notify', function($scope, notify) {}]).service('notify', ['$window',function(win) {
}]);
Directive,
angular.module('docsSimpleDirective', []).controller('Controller', ['$scope', function($scope) {}]).directive('myCustomer', function($scope) {
$scope.enableEditor = function(){
}
return {
template:
};
});
In my project i need to access directive method from angularjs.
For example i have added sample code.
In directive i have enableEditor() method i need to be access this method form my angular services.
I searched on web i did not get proper solution for accessing directive method from angular service.

Camunda Embedded Form: Angular 1.2.16 module config function not firing, can't inject factories or services

I am working Camunda (v7.3.0) for the first time, which uses angular 1.2.16. I am having an issue with the main app module config not firing when the module is loaded. Example:
angular.module('app', []).config(function () {
console.log("inside app config");
})
When the Camunda form is loaded the above module config function is not fired. Example of index.html
<html>
<script src="/my-warfile-process-0.0.1-SNAPSHOT/forms/app.module.js"></script>
<script src="/my-warfile-process-0.0.1-SNAPSHOT/forms/main.controller.js"></script>
<body>
<form ng-app="app" role="form" name="MyCamProcess">
</form>
</body>
When the form is loaded, the app module seems to be only partially bootstrapped if that makes since. angular.module('app') does exist when you run that command in the Chrome console, still the app config is not fired.
The other issues I am having is that, 1) I only define controllers as a separate function ex.
(function () {
angular.module('app').controller("myController", MyController);
var MyController = function ($scope) {
/**
* do controller stuff
*/
};
})();
Not sure if this is angular 1.2.16 thing, I've not work with this version before. 2) I can't inject services or factories in to the controller ex blow
(function () {
angular.module('app').controller("myController", MyController);
angular.module('app').factory("myFactory", MyFactory);
var MyController = function ($scope, MyFactory) {
/**
* do controller stuff
*/
};
var MyFactory = function () {
/**
* do factory stuff
*/
};
})();
The above give me the error throws the dependency error on the injection into the controller.
Another is that the camForm object, it seems that the only way to access to is to embed a script tag in the form tag and either manually inject the object of throw it on the windows object ex.
<form ng-app="app" role="form" name="MyCamProcess">
<script cam-script type="text/form-script">
//add to window object
window.camForm = camForm;
//inject manually
inject(function () {
MyController(camForm);
})
</script>
</form>
Not sure the inject method works, but it does lol. Any help with this would be most helpful :)
UPDATE:
So, I noticed that the controller and services/factories are being added to the invokedQueue, but not actually being invoked:
If you noticed in the image above the invokeQueue has 4 elements, 3 being controllers and 1 being a service. If you look at the controller array the length is 0. Not sure why this is happening.......

AngularJS - Running a function once on load

I am trying to run an $http function when my AngularJS application first loads.
This $http function needs to finish before any of the controllers in my application could properly function. How would I go about doing this? This sounds like a promise, but it sounds like I would be creating a promise in each controller...
I currently have the function that I want to run first like this:
app.run(function() {
$http.get('link').success(function(data) {
// success function. The data that I get from this HTTP call will be saved to a service.
}).error(function(error) {
});
});
However, sometimes the controller will load before the http call finishes.
The problem
Angular is not dynamic, you cannot add controller dynamically neither factory, etc. Also you cannot defer controller bootstrap, angular loads everything together, and it's quite disadvantage (will be fixed in Angular 2)
The cure
But javascript itself has very important feature - closure, which works anywhere, anytime.
And angular has some internal services that can be injected outside of angular ecosystem, even into browser console. Those services injected as shown below. We technically could use anything else (jQuery.ajax, window.fetch, or even with XMLHttpRequest), but let's stick with total angular solution
var $http_injected = angular.injector(["ng"]).get("$http");
The act
First of all, we defer whole angular app bootstrap, inject http service. Then you make your needed request, receive data and then closure get's to work, we pass received data into some service, or we could also assign in to some angular.constant or angular.value but let's just make demo with angular.service, so when your service has data, bootstrap whole app, so that all controllers get initialized with your needed data
Basically that kind of tasks solved like this
<body>
<div ng-controller="Controller1">
<b>Controller1</b>
{{text}}
{{setting.data.name}}
</div>
<hr>
<div ng-controller="Controller2">
<b>Controller2</b>
{{text}}
{{setting.data.name}}
</div>
<script>
//define preloader
var $http_injected = angular.injector(["ng"]).get("$http");
$http_injected.get('http://jsonplaceholder.typicode.com/users/1').then(function(successResponse) {
//define app
angular.module('app', []);
//define test controllers
//note, usually we see 'controller1 loaded' text before 'settings applied', because controller initialized with this data, but in this demo, we will not see 'controller1 loaded' text, as we use closure to assign data, so it's instantly changed
angular.module('app').controller('Controller1', function($scope, AppSetting) {
$scope.text = 'controller1 loaded';
$scope.setting = AppSetting.setting;
$scope.$watch('setting', function(e1 ,e2){
$scope.text = 'settings applied'
});
});
angular.module('app').controller('Controller2', function($scope, AppSetting) {
$scope.text = 'controller2 loaded';
$scope.setting = AppSetting.setting;
$scope.$watch('setting', function(e1 ,e2){
$scope.text = 'settings applied'
});
});
//define test services, note we assign it here, it's possible
//because of javascript awesomeness (closure)
angular.module('app').service('AppSetting', function() {
this.setting = successResponse;
});
//bootstrap app, we cannot use ng-app, as it loads app instantly
//but we bootstrap it manually when you settings come
angular.bootstrap(document.body, ['app']);
});
</script>
</body>
Plunker demo
You can do this when you configure your routes
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'MainCtrl',
templateUrl: 'main.html',
resolve: {
data: ['$http',
function($http)
{
return $http.get('/api/data').then(
function success(response) { return response.data.rows[0]; },
function error(reason) { return false; }
);
}
]
}
});
}]);
Similar question:
AngularJS - routeProvider resolve calling a service method
AngularJS: $routeProvider when resolve $http returns response obj instead of my obj
Heres a plunkr I found using a service, which is what I would recommend.
http://plnkr.co/edit/XKGC1h?p=info

Best way of loading and destroying in angular JS 1.2

I have a scenario where I need to dynamically load an Angular JS application. I have based the code on this:-
https://stackoverflow.com/a/15252490/1545858
Now, I have code that works really well with angular js 1.1.5, but in 1.2.1, no such luck.
Here is the JS code:-
$("#startMeUp").click(function() {
// Make module Foo
angular.module('Foo', []);
// Make controller Ctrl in module Foo
angular.module('Foo').controller('Ctrl', function($scope) {
$scope.data = {};
$scope.data.name = 'KDawg';
$scope.destroy = function() {
$scope.$destroy();
$('#Ctrl').remove();
};
$scope.$on("$destroy", function () {
console.log("EXTERMINATE");
});
});
// Load an element that uses controller Ctrl
$('<div ng-controller="Ctrl" id="Ctrl"> ' +
'<input type="text" ng-model="data.name"></input>' +
'{{data.name}}' +
'<button ng-click="destroy()">Destroy Me</button></div>').appendTo('#container');
// Bootstrap with Foo
angular.bootstrap($('#Foo'), ['Foo']);
});
And here is the HTML:-
<button id="startMeUp">Start Me Up!</button>
<div id="Foo">
<div id="container">
</div>
</div>
Now, if you start and destroy and start again with angular js 1.1.5, everything works fine, but in angular js 1.2.1 it does not work in on the second start. Any thought on how to make it work in 1.2.1?
Here is the js fiddle:-
http://jsfiddle.net/Y9wj2/
As charlietfl says, you don't need to bootstrap more than once. In fact, using angular.js 1.2.1, the error generated that breaks everything is telling you exactly that:
[ng:btstrpd] App Already Bootstrapped with this Element ''
You should think carefully about whether you really need this controller to be dynamic. If you can just use something like ng-include to load the extra content then you will have a much easier time and no need to worry about compiling the content.
If you find you really do need to take this HTML and load it from outside of angular context then you can use the $compile service. Bootstrap the app once somewhere first, preferably using ng-app and grab the injector.
var injector = angular.bootstrap($('#Foo'), ['Foo']);
or
<div id="Foo" ng-app="Foo"></div>
var injector = $('#Foo').injector();
Now you can insert the HTML however you like and then compile and link it using
injector.invoke(['$compile', '$rootScope', function($compile, $rootScope) {
$compile(insertedJqLiteNode)($rootScope);
});

Can't bootstrap an angular app

I was following the angular docs and other links in order to create a "component" with angular inside a rails-based project.
The problem is that I can't correctly initialize the app, and instead I got two identical errors
Uncaught Error: No module: testApp0
Uncaught Error: No module: testApp0
In the following jsfiddle I try to show you my point http://jsfiddle.net/d8Lyu/
I'm pretty new in angular and the official documentation isn't very helpful
You are almost here! Just remember angular is modular and every module need to be declared with an angular.module('my_module_name', ['my_modules_dependency']).
Just refactor your code like that :
angular.module( //this is your app module
'testApp0',
['testApp0.controllers'] //your app need your controller as a dependency to works
);
angular.module( //this is your controller module
'testApp0.controllers',
[]
).controller('sliderCtrl', ['$scope', function($scope) {
$scope.greeting = "hellow" //you pass a gretting variable to your template
}
])
An other thing : you declare a gretting variable in your controller but acces it with user.hellow in your template. Just put {{ gretting }}.
One last thing, in the
frameworks and extensions
of fiddle change 'onLoad' to 'in body', you don't want your angular app to be ready before the DOM.
If you plan to use angular, look at : angular-app. The tutorial app can't be trusted for serious angular developement.
Use this jsfiddle as a reference: http://jsfiddle.net/joshdmiller/HB7LU/
You need to add an external resource, change settings in the 'fiddle options' section and the 'frameworks and extensions' section.
Once everything is setup you can create your angular in the javascript pane likeso:
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Superhero';
}

Resources