node.js exporting methods facade design pattern - javascript

I am trying to follow the facade design pattern in a node.js application where I have on object that is used with the rest of the application called controller.js as the facade. The controller controls calls to objects user.js, animal.js, and house.js which are all separate files.
In controller.js I do
var housecontroller = require("./controllers/housecontroller");
...
I want to call something like controller.getHouse() in another file (client). How do I make it so that I can do that and not have to call housecontroller.getHouse()?
Each of my controllers are formatted as follows
module.exports = {
getHouse:function(){...},
...
}
I'm a bit confused on how to properly export things in order to get this to work. I import/export the controllers and their methods in controller.js as follows
module.exports = {
getHouse : housecontroller.getHouse,
...
};
I use only the house in the examples but it's implied I do the same for user and animal which all have several methods. In the client, I just import controller.js and use its methods.
var controller = require("./controller");
controller.getHouse();

According to your code/naming you could have a file controller.js in controllers folder with something like this
var housecontroller = require('./housecontroller');
var carcontroller = require('./carcontroller');
module.exports = {
getHouse: housecontroller.controller,
getCar: carcontroller.controller
};
The client code could be:
var controller = require('./controllers/controller');
controller.getHouse();
I added carcontroller as example of extension.
If you only have one function to offer from each controller you can change your code and these examples to:
//housecontroller.js
module.exports = getHouse;
//controller.js
var housecontroller = require('./housecontroller');
var carcontroller = require('./carcontroller');
module.exports = {
getHouse: housecontroller,
getCar: carcontroller
};
Although I don't recommend it because you are reducing the opportunity to offer more functions from that module in the future

Related

IOC in AngularJS (1.x) - How can I achieve?

I'm looking for some way to add IOC to my angularjs application.
My app is a multi tenant app and I need to use different services for different tenants with the same registration name.
I'm using TypeScript as well and it works well with using concrete types over interfaces.
My main problem is how can I decide how to register the correct service to my application.
This is an example:
var app = angular.module('app',[]);
// common registrations
app.service('commonService1', commonServiceFunction1);
app.service('commonService2', commonServiceFunction2);
app.service('commonService3', commonServiceFunction3);
app.service('commonService4', commonServiceFunction4);
// here I want to register the same service name with a different implementation
app.service('serviceName', serviceOneFunction); // sometimes I will need this service
app.service('serviceName', serviceTwoFunction); // sometimes I will need this service
Things I thought about:
Add some logic and download the correct js files per source - Function names will stay the same and I will need to figure out a way to provide the correct js file that includes the correct functions.
Override the registrations (e.g. register the common service and then override the registration with a specific implementation).
Both solutions ugly and not scalable to me.
I would like to have a IOC container or some other solution that is a bit more nice and scalable.
If I have understood question correct, you can register services(which are actually providers) as provider which you configure at angular configuration step.
So, it may look like this:
var app = angular.module('app',[]);
// common registrations
app.service('commonService1', commonServiceFunction1);
app.service('commonService2', commonServiceFunction2);
app.service('commonService3', commonServiceFunction3);
app.service('commonService4', commonServiceFunction4);
app.provider('serviceName', function ServiceNameProvider() {
var service = DefaultService;
this.setService = function(newService) {
service = newService
}
this.$get = [function() {
return service;
}];
});
app.config(["serviceNameProvider", function(serviceNameProvider) {
if(someCondition) {
serviceNameProvider.setService(ServiceImpl1);
} else {
serviceNameProvider.setService(ServiceImpl2);
}
}]);
Services, factory are just syntactic sugar over provider. You can determine your service function at configuration stage of angular. ServiceImpl1, ServiceImpl2 are just functions but you can use dependency injection there as they will be called by provider with $injector.invoke. Read about providers
Hope this will help you. Try Using angular factory.
angular.module('app').factory('tenantService', function() {
var tenantService = undefined;
if(tenantType == "1"){
tenantService = new TenantService1();
} else if(tenantType == "2"){
tenantService = new TenantService2();
} else {
tenantService = new TenantDefService();
}
return tenantService;
});

In a Node app with express JS, how can I include and run a separate JS file?

I have a javascript file that contains some functions that grab an RSS feed and save the contents in a database. I originally had it being called by the HTML page, but I want this file to instead be running in the back-end all the time (grabbing updates from the RSS feed and saving it to a database).
My question is, how can I attach and run this separate javascript within my app? I assume it will look like this:
In app.js:
var RSSReader = require('./public/javascripts/RSSReader.js');
RSSReader.SomeFunction();
This isn't working though. Also, would variables declared in my app.js be available in RSSReader.js?
Thanks.
how can I attach and run this separate javascript within my app?
The app.js code you show should work just fine. The key is that you have to make your RSSReader.js file into a module that exports the functions it wants to be public:
So, inside of RSSReader.js, you would have something like this:
module.exports = {
someFunction: function() {
// code here
},
someOtherFunction: function() {
// code here
}
};
Then, in your other file, you can load that module and use it like you had:
var RSSReader = require('./public/javascripts/RSSReader.js');
RSSReader.someFunction();
RssReader.someOtherFunction();
node.js documentation for modules is here.
Also, would variables declared in my app.js be available in
RSSReader.js?
No, they would not unless you explicitly declared the app.js variables as properties on the global object. The usual node.js convention for sharing from app.js to another module is that you create an initializer method for the RSSReader.js module (you can call it init) and you pass it any context it needs (usually an object with some properties on it) from app.js and the RSSReader.js module can then store that context for its use.
So, if you want to share some variables from app.js to RSSReader.js, you could share them via a .init() method like this:
RSSReader.js
var data;
module.exports = {
init: function(options) {
data = options;
},
someFunction: function() {
// code here can access the data variable
},
someOtherFunction: function() {
// code here can access the data variable
}
};
app.js
var RSSReader = require('./public/javascripts/RSSReader.js');
RSSReader.init({express: express, db: db});
RSSReader.someFunction();
RssReader.someOtherFunction();

AngularJS reusable factory

I feel like this is probably a dumb question but I'm having trouble visualizing how to make this work.
I have a factory used to share data between controllers, like this:
app.factory('DataShare', function(){
//Share Data between controllers via the sharedItem object and the get/set functions
var sharedItem = {};
function set(sharedData){
sharedItem = sharedData;
}
function get(){
return sharedItem;
}
return{
set: set,
get: get
};
});
It works just fine. The issue is that are several times in my application where I need to share data. Currently, I have multiple factories with different names containing the same methods shown above. Can someone advise on the best way to create an abstract factory that I could reuse to share different data between different controllers?
Create a new file and declare a new object.
var mySharedLib = mySharedLib || {}; // declare a new namespace for the shared code.
mySharedLib.DataShare = function() {
// your factory logic
}
Then, the angular side:
app.factory('DataShare', mySharedLib.DataShare);

expressjs conditional view render path

I'm writing an app using expressjs. I have my views in, commonly, /views folder. They cover 90% of my customers' needs, but sometimes I have to override one or another of those view to add custom-tailored features. I really wonder I can build a folder structure like:
*{ ...other expressjs files and folders...}*
/views
view1.jade
view2.jade
view2.jade
/customerA
view2.jade
/customerB
view3.jade
What I'd like is to override the behaviour of expressjs' response.render() function to apply the following algorithm:
1. a customer requests a view
2. if /{customer_folder}/{view_name}.jade exists, than
render /{customer_folder}/{view_name}.jade
else
render /views/{view_name}.jade
Thus, for customerA, response.render('view1') will refer to /views/view1.jade while response.render('view2') will refer to /customerA/view2.jade
(those who use appcelerator's titanium may sound it familiar)
I'd like an elegant way to implement this behavior without the hassle of modify expressjs' core functionality, and thus possibly get treated at upgrading my framework. I guess it's a common problem but I can't find any article on the web.
I would create a custom View class:
var express = require('express');
var app = express();
var View = app.get('view');
var MyView = function(name, options) {
View.call(this, name, options);
};
MyView.prototype = Object.create(View.prototype);
MyView.prototype.lookup = function(path) {
// `path` contains the template name to look up, so here you can perform
// your customer-specific lookups and change `path` so that it points to
// the correct file for the customer...
...
// when done, just call the original lookup method.
return View.prototype.lookup.call(this, path);
};
app.set('view', MyView);
You can hook http.ServerResponse.render.
Here's some code from the top of my head, to be used as middleware:
var backup = res.render
res.render = function() {
//Do your thing with the arguments array, maybe use environment variables
backup.apply(res, arguments) //Function.prototype.apply calls a function in context of argument 1, with argument 2 being the argument array for the actual call
}

In Ember.js, how do you hook an object into a generic application namespace

Let's say I declared an application namespace:
App = Ember.Application.create();
and later I write an arrayController instance that creates objects and hook it onto the app namespace on user event:
App.objController = Ember.ArrayController.create({
content: [],
createObj: function(){
// instantiate new object
var newObj = Ember.Object.create({ ... })
//give obj a name
var newObjName = this._getObjName( someParam );
// hook object to an app namespace -> this is where I have an issue
App[newObjName] = newObj
},
...
});
See I explicitly use App[newObjName] = newObj to hook the object onto the namespace, ideally I would like some sort of generic way to name the application namespace in case I use the objController for a different application later.
There has to be some way to do this though I am just not familiar enough with Ember to have encountered it.
Note: on a scale of 1 to JFGI, this question is definitely not a 1. On the other hand it's a free resolved checkmark for anyone that has a moment.
During the initialization phase, Ember will instantiate all of your controllers and inject three properties into each of them - "target", "controllers", "namespace". The "namespace" property is your application.
That said, instead of hard-coding the top-level object:
App[newObjName] = newObj
you can do the following:
this.get("namespace").set(newObjName, newObj);
Note - in order for this to work, your application needs a router. Also, you should define controller classes, not instances. Ember will instantiate all controllers for you. So, this
App.objController = Ember.ArrayController.create({/* code here */});
should be written as
App.ObjController = Ember.ArrayController.extend({/* code here */});
Note the capital "O" in "ObjController".
Consider using injections, which is the preferred way to add dependencies.
Ember.Application.registerInjection({
name: 'fooObject',
before: 'controllers',
injection: function(app, router, property) {
if (property === 'FooObject') {
app.set('fooObject', app[property].create());
}
}
});
So if you define a class as follows:
App.FooObject = Ember.Object.extend({
// ...
});
the injection will create an instance into App.fooObject. Although we still use the namespace App, however only once. You could further do:
Ember.FooObject = Ember.Object.extend({
// ...
});
and then in your App, App.FooObject = Ember.FooObject but I'm not sure if its useful.

Categories