I'm building a web app with node.js (+ angular, etc.).
The app will have to retrive some data (something like a catalog items list) from different providers, who expose their data in different ways.
In that module, I will have some function common to all providers, and some function unique to any of them.
My current (poor) implementation is something like this:
var providers = [
{ name: 'Apple', /* ... */ },
{ name: 'Samsung', /* ... */ },
{ name: 'Google', /* ... */ },
];
exports.syncCatalogues = function(search, callback) {
var allItems = [];
for (var p = 0; p < providers.length; p++) {
exports.getCatalog(providers[p], function(err, catalog) {
if (err) {
return callback(err);
}
exports.getItems(providers[p], catalog, function(err, items) {
if (err) {
return callback(err);
}
allItems = allItems.concat(items);
callback(null);
});
});
}
};
And my getCatalog() and getItems() implementation are as ugly as this:
exports.getCatalog(provider, callback) {
if (provider.name === 'Apple') {
// code for Apple provider ...
}
// and so on ...
};
exports.getItems(provider, callback) {
if (provider.name === 'Apple') {
// code for Apple catalog ...
}
// and so on ...
};
I know with ES5 (I'm stuck to it) abstract classes are not easy to implement, but I'm sure there is a better way (code more readable, maintainable, testable) than this... :-(
There are many ways to implement the inheritance in JavaScript. Here is one, which I think the simplest, since you just operate with plain objects and use prototypal inheritance.
Instead of the base class you have a prototype object where you can place the common code. Then you create an object based on the prototype and add specific code to it.
var providerPrototype = {
name: 'Prototype',
alertName: function() { // this is common function, all objects
alert(this.name); // will have it
}
};
var appleProvider = Object.create(providerPrototype);
appleProvider.name = 'Apple';
// this is a specific function for 'Apple'
appleProvider.getCatalog = function(callback) {
return callback(null, ['iPhone', 'Mac Mini']);
}
appleProvider.alertName = function() {
// call 'base' method
providerPrototype.alertName.call(this);
alert('All rights reserved.');
}
var samsungProvider = Object.create(providerPrototype);
samsungProvider.name = 'Samsung';
// this is a specific function for 'Samsung'
samsungProvider.getCatalog = function(callback) {
return callback(null, ['Galaxy S3', 'Galaxy S4']);
}
var providers = [
appleProvider, samsungProvider
];
var syncCatalogues = function(search, callback) {
var allItems = [];
for (var p = 0; p < providers.length; p++) {
var aProvider = providers[p];
aProvider.getCatalog(function(err, catalog) {
if (err) {
return callback(err);
}
aProvider.alertName(); // call the base method
alert(catalog);
});
}
};
syncCatalogues();
Check also Inheritance and the prototype chain in Mozilla javascript documentation.
And here is an example of splitting classes over node.js modules.
I'm new in nodeJS but I think my code below is possible only after ES6. I hope to help newbies like me. Follows:
class BaseClass {
constructor(){
console.log('Object created INHERITED');
}
toCallFromChild(){
console.log('Called by child');
this.toOverride();
}
toOverride(){} //to override
}
class childClass extends BaseClass{
toOverride(){
console.log ('Override by child');
}
}
var instance = new childClass();
instance.toCallFromChild();
My response is a possible alternative solution.
I personnally do not like the native javascript object mecanics. So i generaly use a library like Mootools for making clean objects.
Example from Mootools documentation :
var Animal = new Class({
initialize: function(age){
this.age = age;
}
});
var Cat = new Class({
Extends: Animal,
initialize: function(name, age){
this.parent(age); // calls initalize method of Animal class
this.name = name;
}
});
var myCat = new Cat('Micia', 20);
alert(myCat.name); // alerts 'Micia'.
alert(myCat.age); // alerts 20.
Se the online doc on : http://mootools.net/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With