Can I write directive that is decoupled from the main app? - angularjs

I am starting to write a little library that uses angular. I want to write a directive that is not coupled to the first app that is initialized. I want to write a directive that somebody would add to their app and it would just work.
Instead of:
angular.module('realEstateApp', []);
angular.module('realEstateApp').directive(etc);
Just use:
angular.directive(etc)
If I can't do this, do you have some workaround to give me?

Angular directives need always to live within a module. What you have to do is define a module and then use it as a dependency in other modules. People will have to add Your module as a dependency to theyr module:
angular.module('myDirectiveModule', []);
angular.module('myDirectiveModule').directive(etc);
Then share your module, and people will have to do (after including your script):
angular.module('myModule', ["myDirectiveModule"]);

Related

What is needed for referencing custom module?

I cannot find example which shows the last step of building/using custom module -- referencing it in code. Let's say I have such line in my custom module:
angular.module('shared', []).factory('Factory', [Module]);
Then in my main app, I declared the dependency:
let app = angular.module('admin',[
"shared",
]);
So far, so good. The question is how do I access this shared? In my case it is undefined. What do I miss?
You can now inject elements in admin module that are registered in shared, like factories, controllers, providers, directives etc.
So you can inject Factory to some factory in your admin module.

AngularJS: injecting a dependency to the main module or to a controller?

I'm confused about something. Some dependencies have to be injected to the main module. For example:
angular.module("app", ["ui.router", "ui.bootstrap", "toaster"]);
Whereas some other dependencies can just be injected into the controllers, but don't need to be injected into the main module. For example:
angular.module("app").controller("newCtrl", ["$q", newCtrl);
I'm having difficulties understanding why. Any help will be much appreciated.
$q a service within the core ng module, per the documentation.
All services within the ng module are bootstrapped and registered when the angular.js file is loaded and parsed. This allows you to inject them anywhere in your app.
However, the three examples you have listed above are all external, modular dependencies. They need to be explicitly registered into your application so that the components within are available when the $injector service attempts to resolve them.
You inject modules into other modules.
You inject providers, services, and factories that are included in those modules into the specific controllers.
In Angular, you define a module like so:
angular.module('MyModule1', []);
Notice how module function takes two arguments. Second argument being the array of other modules this module is dependent on. This construct is for setting a module.
Once the module is defined, you can attach controller, services etc. to the module.
angular
.module('MyModule1')
.service('MyService1');
Notice, how this time only one argument was give to the module function. That means you are getting an already registered module.
Lets say you create another module MyModule2, but MyModule2 needs to use the services defined by the MyModule1.
You just set the module MyModule2 with MyModule1 as its dependency.
angular.module('MyModule2', ['MyModule1']);
Now, you want to create a controller (or a directive, or a service, whatever) in MyModule2 that actually makes use of the service MyService1 defined in MyModule1.
That's where the Dependency Injection (DI) of Angular comes in. You define your controller with the service name as function parameter and when Angular instantiates your controller, it makes sure the service instance is found and provided to your controller.
angular
.module('MyModule2')
.controller('MyController2', function (myService1) {
// Hey I can use myService1
// Dependency Injection FTW!
});

Webpack with angular 1.x and ES5

After reading hundreds of lines about browserify vs webpack and several how to of both I decided to go for webpack. The main reason it's because I liked the idea of bundling everything into a js file.
I have an angular project already working and I want to refactor it for webpack. The problem? My project is using angular 1.4.7, ng-animate and plain javascript (ES5) and all the tutorials and manuals are for ES6. I don't want to refactor my project so much. What's the way to go? I would like an example of each angular module : factory, directive, controller and so on. Many thanks
I typically have a feature.module.js file which has my module definition and requires all of the directives / services contained within the module. Also has the external dependancies.
/* module.js */
angular.module('my.module',['dependancy1', 'dependancy2']);
//External libraries
require('./dependancy1.module.js');
require('./dependancy2.module.js');
//Internal components
require('./thing.directive');
require('./thing.service';
/* service.js */
angular.module('my.module')
.directive('yourDir', function myDir(){...});
I'm dealing with the same problem now. And I found something that works (work in progress, but at least I can see progress). My steps:
Install yeoman
Run this angular-webpack generator. Select 'ES5' when asked (the other option is 'ES2015', which I guess is the same that 'ES6')
Start modifying the automatically generated boilerplate with your Angular code
Yes, you still need to learn about gulp and sass, but at least you can run a simple AngularJS app using the old ES5 syntax, and start modifying it.
I'm probably blogging about this. So, I'll update this answer then.
I tend to do this:
app.js:
require('/any/angular/deps');
var subModule = require('/some/sub/module');
var app = angular.module('myApp', []);
// pass the app module in sub modules to allow them to define their own config
subModule.configure(app);
/subModule/module.js:
var someSubDirective = require('./subDir/directive');
export function configure(app) {
someSubDirective.configure(app);
}
/subModule/subDir/directive.js:
export function configure(app) {
app.directive('myDir', myDir);
}
function myDir() {
}
My idea is to let all sub modules handle their own configuration, so declaring config or constant, factories or providers. Letting this then bubble up to the app.js. This means its really easy to delete a folder from your structure, because it is one line removal from it's parent module.
This also makes relevant file paths a lot shorter and easier to handle.

How can I create an angular service for use in different modules?

I see in the angular documentation for creating services that a service is created by definining a factory on a module.
However I need to define a common service for use across multiple modules.
I am not seeing any thing in the documentation for that. Can it be done? Or is there some way to access a service from a module other than the module it was created on?
Please check working demo: JSFiddle.
Define a service in some common module like:
angular.module('mySharedModule', [])
.service('mySharedService',...
Then in other modules, use
angular.module('myModule', ['mySharedModule'])
.controller('mySharedService', function (mySharedService) {
...
Then you can use mySharedService inside the module myModule. Your service is now injectable to it.
A service has to belong to a module. However, to use it in other modules, just include the owning module in the modules where you would like to use it. Example:
angular.module('common', [])
.factory('yourService', ...);
angular.module('yourModule', ['common'])
.controller('yourController', ['yourService', function(yourService) {
// common service available here.
}]);

Why a service of main module available in other modules?

I have a main module main which contains a service mainService. I have then injected another module moduleA in my main module. I randomly called mainService in moduleA without injecting main module and was amazed to see it is working fine.
angular.module('main', ['moduleA']);
angular.module('main').service('mainService', function(){
//insert code here
});
angular.module('moduleA', []);
angular.module('moduleA').controller('abc', function(mainService){
//mainService available here, without injecting main module
});
I want to know the reason behind this. I once read in a comment that a service defined in a module is available everywhere in the application, but couldn't find the source. Is it ok to continue using it like this?
I'm using AngularJS ver 1.3.15 if it helps.
Yes you can use the service of main because of parent child relationship. "main" is a parent module and "moduleA" its child/dependency module.
Any serivce, controller, directive defined in "main" module will be available with "moduleA"
Lets understand this concept with a more complex scenario
angular.module('main', ['moduleA', 'moduleB']);
angular.module('moduleA', []);
angular.module('moduleA').service('moduleAService', function(){
//insert code here
});
angular.module('moduleB', []);
angular.module('moduleB').controller('abc', function(moduleAService){
//moduleAService available here, without injecting moduleA module
});
Now in this case moduleA and moduleB are totally independent but still moduleB can access moduleA services
It is because main module is dependent on moduleA and moduleB. So moduleA services is injected in main module and moduleB being a child of "main" module can access it.
Injecting something like a service in the parent, makes it available to all its children.
Worth reading http://michalostruszka.pl/blog/2015/05/21/angular-dependencies-naming-clash/ to know few more things about modules.
Summary from the post:
It turns out AngularJS doesn’t really care where it takes things to inject from as long as the name matches
In AngularJS there is no such thing as module you depend on. Even when you ask for a thing, you cannot be sure you’ll get the one you expect just because you declare dependency on module that has exactly this thing. This is all one giant toolbox.

Resources