Combining Angular Services with NodeJS Modules - javascript

Supposing I have a library written in Javascript to be used in a MEAN stack application.
I wish to use my library both from NodeJS and within Angular.
To remain idiomatic I would like the library to appear as a Module inside node and as a Service within Angular.
the only way I can think to do this is to do something like:
var myLibrary = function(){
var myLib = {};
myLib.myFunc1 = function() {
//Do some cool stuff
};
return myLib;
};
if (typeof module !== 'undefined') {
module.exports = myLibrary();
} else{
var app = angular.module('myApp.services', []);
app.factory('myLibrary',myLibrary);
}
This will work, but it has at least two significant limitations:
The namespace is polluted with the variable "myLibrary"
If within the library I want to use other node modules or Angular services then I can't
I would like to know if anyone knows of a better solution, or if I should give up on using Angular services and use one of the libraries that allows client side Node module functionality.

Having done a bit of searching about this looks like the best solution:
https://gist.github.com/sevcsik/9207267

Related

Nodejs, is better have a lot of same require or use a handle?

Image this esctructure:
- app.js
- core/
- service_1.js
- service_2.js
- service_3.js
- service_4.js
- service_5.js
- modules/
- module_1.js
- module_2.js
- module_3.js
The app.js uses the 3 modules, so the code of the app is:
var m1 = require('./modules/module_1');
var m2 = require('./modules/module_2');
var m3 = require('./modules/module_3');
m1.exec();
m2.exec();
m3.exec();
And each model uses all the services, so they need:
var s1 = require('./../core/service_1');
var s2 = require('./../core/service_2');
var s3 = require('./../core/service_3');
var s4 = require('./../core/service_3');
var s5 = require('./../core/service_3');
// some stuff...
So, I need to know if this is the best way to handle that or maybe do a "serviceManager" like:
app.js
var m1 = require('./modules/module_1');
var m2 = require('./modules/module_2');
var m3 = require('./modules/module_3');
var serviceManager = {
service_1 : require('./core/service_1'),
service_2 : require('./core/service_2'),
service_3 : require('./core/service_3'),
service_4 : require('./core/service_4'),
service_5 : require('./core/service_5')
};
m1.load(serviceManager);
m2.load(serviceManager);
m3.load(serviceManager);
m1.exec();
m2.exec();
m3.exec();
And each model I put:
var serviceManager = null;
exports.load = function(services) {
serviceManager = services;
}
// some stuff...
What is the best if I gonna use that class in almost all my files?
a) Get a lot of 'require'.
b) A handle to put 'require' only one time.
c) Another solution.
Dependency injection is really good for this. I've used and recommend insulin. This makes it very easy to load each of your modules in the dependency injection container and then just name dependencies in the modules you write.
You might do something like the following:
'use strict';
require('insulin').factory('myService', myServiceFactoryFunction);
function myServiceFactoryFunction(dependencyOne, dependencyTwo) {
// Do something with your dependencies.
}
This way you require once at the top of the file and never have to do it again in that file.
As mentioned in one of the other answers, node caches everything required, so each time you require the injection container, you get the same one. This makes it very quick and easy to build your app without either having to require things everywhere or pass things around.
Later, to get the module you created above you would just do the following where it's needed:
'use strict';
require('insulin').factory('mySecondService', mySecondServiceFactoryFunction);
function mySecondServiceFactoryFunction(myService) {
// myService is now available in this module
}
Insulin, as with most other dependency injectors you might use has other methods if you for some reason don't want to or can't rely on injection in some part of your application. You could do something like:
const insulin = require('insulin');
const myDependency = insulin.get('someModule');
where needed.
The best part about this to me is that the code becomes really clean and it's easy to tell what the dependencies are for a given file just by looking at the arguments passed to the factory function.
I would go with a lot of requires. It does not matter, because Node.js caches the modules after first load.
From the Node.js docs:
Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.

How do you manage namespace in Meteor?

So here is my problem :
Currently, I have a dozen of functions related to WEBRTC within a template js file. My objective is to have those functions in a separate file, called webRTCWrapper.js for example, and to call those functions in my template without using global variable.
I think I must use namespaces, am I correct ?
If so, how do you use them ?
EDIT : For anyone interested, this is exactly what I was looking for :
http://themeteorchef.com/snippets/using-the-module-pattern-with-meteor/
Make a directory called packages/ parallel to your .meteor/ directory. You can create a package that exports a single object/function. On the command line, use meteor create --package <yourpackagename> and meteor add <yourpackagename> You can edit the js file to add a namespace.
MyNamespace = {};
MyNamespace.myFunction = function () { };
Then, in the package.js, simply export that namespace.
api.export('MyNamespace');
You can use a common pattern of having a global object and your functions inside that object.
Greetings = {
hello: function(name) { return "Hello "+name+" how are you?"; }
}
And then you can call it inside the template helpers :
Template.GreetingsTemplate.helpers({
sayHello: function() { return Greetings.hello('Maxence'); }
})
Take note of the loading order of files in Meteor, anything inside the lib folders is loaded first. If you run into problems where "Greetings" object is not defined, then its because that file was not loaded already.
Edit:
You can reuse the same pattern for adding more functions in different files (you could use App = App || {} but it will throw error in Chrome for example).
App = (typeof App === 'undefined')? {} : App;
App.someFunction = function(){};
or even, if you use underscore.js:
App = (typeof App === 'undefined')? {} : App;
_.extend(App, {
someFunction: function(){}
});
Since now the regular way to use the code from another file was going through a global (server and client). As Joao suggested you can make your own global App variable where you will store or more generically a global MODULE one (basically the same solution as Joao but with explanation).
But with with the arrival of ES2015 support, we will very soon be able to have an official pattern to achieve this. However as the 1.2 does not supports yet the import/export syntax:
Note, The ES2015 module syntax (import/export) is not supported yet in Meteor 1.2.
If you want to start using those features earlier, I would recommend using this package which is an temporary solution to fill the current import/export gap, the meteor team development are currently looking for an elegant solution to support this.

AngularJS - module dependencies, naming clash

I have two third-party modules, both defining a factory with the same name. Obviously, I don't have any control over the naming of those modules without resorting to a kludge.
Additionally, I have two further, internal modules, each using a different one of the two third-party modules as a dependency (as below). I was sure that I was unable to access components from a module not listed in current module's dependencies, but it turned out I was wrong.
Here even if own1 depends on thirdParty1 (which has hello defined as hello world) it's getting hi there (from thirdParty2) in controller. The same is for the other modules' pair.
Is there any way to "isolate" modules so I can only use stuff that I explicitly depend on? If not, what's the point of having modules if I can reach anything at any time (assuming main app module has it as its dependency)? Also if I have two modules with components named hello how can I tell which is gonna be used?
Here is jsbin for that http://jsbin.com/vapuye/3/edit?html,js,output
angular.module('app', ['own1', 'own2']);
//third-party modules
angular.module('thirdParty1', []).factory('hello', function () {
return 'hello world';
});
angular.module('thirdParty2', []).factory('hello', function () {
return 'hi there';
});
// "own" modules
angular.module('own1', ['thirdParty1']).controller('Own1Ctrl', function(hello) {
this.greet = hello;
});
angular.module('own2', ['thirdParty2']).controller('Own2Ctrl', function(hello) {
this.greet = hello;
});
And the result of:
<body ng-app="app">
<div ng-controller="Own1Ctrl as own1">
Own1: {{ own1.greet }}
</div>
<div ng-controller="Own2Ctrl as own2">
Own2: {{ own2.greet }}
</div>
</body>
Is :
Own1: hi there
Own2: hi there
You can request a factory of a certain module explicitly (without dependency injection):
var injector = angular.injector(['thirdParty1']);
var hello1 = injector.get('hello');
var injector = angular.injector(['thirdParty2']);
var hello2 = injector.get('hello');
You can also use this, to wrap the third party factories into own factories:
angular.module('own1', ['thirdParty1']).factory('hello1', function () {
var injector = angular.injector(['thirdParty1']);
var hello = injector.get('hello');
return hello;
});
angular.module('own2', ['thirdParty2']).factory('hello2', function () {
var injector = angular.injector(['thirdParty2']);
var hello = injector.get('hello');
return hello;
});
This allows you to use hello1 and hello2 in all other parts of your application.
Since there is no built-in name spacing of modules (or components of modules) the best way to achieve your goal is to use a unique naming convention for your modules. Most libraries for angular do this, and then you should be good to go.
Besides encapsulating your applications behavior, modules help testing and mocking your application.
I dont think it is possible for angular to differentiate between two components that are named the same (I think this changes with angular 2). And I might argue that two components that are named the same might do the same and you should look why you need both?

Javascript - accessing namespace in different files

I can do this in node.js
var module = require('../path/module')
module.functionname()
So I thought I'd like to do that in client side Javascript to organize things slightly.
So each of my files now has a namespace. So say login.js has a namespace login.
My question is, what's the best way in ECMAScript 5 to implement something alongs these lines?
What you are trying to achieve can be done with AMDs (asynchronous module definitions). Check out RequireJS for that: http://requirejs.org/
With Require.js you can basically define a set of dependencies, let them get loaded asynchronously and execute code once all stuff was loaded nicely:
require(['dependency1.js', 'dependency2.js'], function(dep1, dep2) {
console.log(dep1.functionname())
})
The dependency will then declare it's functionalities with require's define method:
define(['a/possible/dependency.js'], function() {
return {
functionname: function() { return 1 }
}
})

How should I think about my JavaScript application namespaces?

I'm building an app that has a single global namespace like so:
var myApp = {};
I then have a bunch of different reusable "modules" comprised of models, views and controllers.
//Bar chart module code
org.example.chart.bar.module
org.example.chart.bar.model
org.example.chart.bar.view
org.example.chart.bar.controller
I also have a big dataSource singleton and a dataManager for loading data to the dataSource:
org.example.data.dataSource
org.example.data.dataManager //populates the dataSource with CSV data
And finally translation strings and settings that should be available across the app:
org.example.static.translations
org.example.static.settings
How would you (re-)organize this so that I have easy access to the application level singletons (such as dataSource, dataManager, translations etc.) and can easily instantiate reusable modules that get scoped under the current application instance?
(Would you for example, already from the beginning, use the same namespace for your "classes" and your app? Or would you perhaps make references like so: myApp.translations = org.example.static.translations?)
No we don't namespace. We write modular code and we use module loaders.
Example of a module loader would be require.js or browserify or seajs.
And an example module would be something like:
(function () {
var jQuery = require("jQuery");
var chart = require("chart");
...
define("moduleName", moduleObject);
})();
There is nothing stopping you adding another name to the class. For example.
org.ds = org.example.data.dataSource;
then you can call
org.ds.getDatasource();
instead of
org.example.data.dataSource.getDatasource();
but both will still work.
EDIT: You could also create other simpler functions that call it taking it out of the oo structure
var dataSource = function () { return org.example.data.dataSource.getDatasource(); };
Consider using something like RequireJS for organizing your modules.
Some excellent resources from Addy Osmani :
http://addyosmani.com/largescalejavascript/
http://addyosmani.com/blog/large-scale-jquery/
http://addyosmani.com/resources/essentialjsdesignpatterns/book/

Categories

Resources