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