Nodejs util.inherits produce unexpected results - node.js

Following code always prints 3 3 where as it should be printing 2 3 anything in any suggestions as to what I am doing wrong here ? or this is expected ?
var EventEmitter = require("events").EventEmitter,
util=require('util');
var Car=function(){
var self=this;
EventEmitter.call(this);
var make=1;
Car.prototype.getMake = function() {
return make;
};
Car.prototype.setMake = function(val) {
make=val;
return make;
};
}
util.inherits(Car, EventEmitter);
function Bmw(){
Car.call(this);
}
function Merc(){
Car.call(this);
}
util.inherits(Bmw, Car);
util.inherits(Merc, Car);
var car1=new Bmw();
car1.setMake(2);
var car2=new Merc();
car2.setMake(3);
console.log(car1.getMake(),car2.getMake());

var Car = function(){
var self=this;
EventEmitter.call(this);
var make=1;
Car.prototype.getMake = function() {
return make;
};
Car.prototype.setMake = function(val) {
make=val;
return make;
};
};
does not make sense. Car.prototype.getMake affects every single instance of Car, so what you are basically saying is, every time a new Car() instance is created, change the getMake and setMake function on ALL instances back to 1. Then when you call setMake it changes the make value for every instance
You either need to assign them explicitly to a single instance of Car. e.g.
var Car = function(){
EventEmitter.call(this);
var make=1;
this.getMake = function() {
return make;
};
this.setMake = function(val) {
make=val;
return make;
};
};
Or keep them on the prototype and use a different method for passing the value of make into the functions.
var Car = function(){
var self=this;
EventEmitter.call(this);
this.make_ = 1;
};
Car.prototype.getMake = function() {
return this.make_;
};
Car.prototype.setMake = function(val) {
this.make_ = val;
return this.make_;
};

Related

Resolving a deferred Q multiple times

As I know deferred can be resolved only once and also nodejs caches the required module at the first step in order to prevent loading it every single time, but what I want to do is renewing deferred Q object each time I want to resolve/reject a returned value.
This is my server code :
// server.js
app.get('/api/posts', function(req,res,next){
var insta = require('./upRunner'); // this's the main obstacle
insta.returner().then(function(data){
// ....
};
});
and the code for ./upRunner.js is :
// upRunner.js
...
var defer = Q.defer();
upRunner();
function extractor(body) {
var $ = cheerio.load(body), scripts= [];
$('script').each(function(i, elem){
scripts[i] = $(this).text();
});
var str = scripts[6],
newData = JSON.parse(str.substring(str.indexOf("{"), str.lastIndexOf(";"))).entry_data.TagPage[0].tag.media.page_info;
grabber(str);
return newData;
}
function grabber(str) {
newData = JSON.parse(str.substring(str.indexOf("{"), str.lastIndexOf(";"))).entry_data.TagPage[0].tag.top_posts.nodes;
newData.sort(dynamicSort('-date'));
newData.forEach(function(elem,index,array){
if (instaImages.length >= 10) {
defer.resolve(instaImages);
} else {
instaImages.push(elem);
}
});
}
function upRunner(newData){
profilePage = !(tagPage = URL.includes("/tags/") ? true : false);
if (!newData) {
request(URL,{jar:true}, function(err, resp, body){
var $ = cheerio.load(body), scripts= [];
$('script').each(function(i, elem){
scripts[i] = $(this).text();
});
var str = scripts[6],
newData = JSON.parse(str.substring(str.indexOf("{"), str.lastIndexOf(";"))).entry_data.TagPage[0].tag.media.page_info;
upRunner(newData);
});
} else {
if (newData.has_next_page) {
requester(URL, newData.end_cursor).then(function(body){
newData = extractor(body);
upRunner(newData);
});
} else {
console.log('it\'s finished\n');
}
function returner() {
return deferred.promise;
}
exports.returner = returner;
As you see I'm almost renewing upRunner returner deferred promise each time server get /api/posts address, but the problem is the deferred object still return the old resolved value.
There is the grabber function which resolve value, so defer can not be localized in a single function.
Try to initialized deferred value locally to get new resolve value.
function returner() {
var defer= $q.defer();
return deferred.promise;
};
exports.returner = returner;

Variable precedence (global in node js?)

"use strict";
var Tabletop = require("tabletop");
var base64 = require('base-64');
Tabletop.init( { key: 'xxxxxg46hgfjd',
callback: showInfo,
simpleSheet: true } )
function showInfo(data, tabletop) {
console.log(data);
console.log(base64.encode(data));
}
var vGlobals = {
dataString: base64.encode(data)
};
module.exports = vGlobals;
How can I access the data variable from showInfo, to use in vGlobals? It says that it hasn't been defined.
Your approach is wrong, you can't do it this way because TableTop call your callback asynchronously.
My suggestion (a quick one) :
var dataString = null;
module.exports = function(cb) {
if (dataString == null)
Tabletop.init({
key: 'xxxxxg46hgfjd',
callback: function(data, tabletop) {
dataString = base64.encode(data);
cb(dataString);
},
simpleSheet: true
});
else cb(dataString);
};
And to get the data :
var dataManager = require('./myfile');
dataManager(function(dataString) {
//here is your data do what you want with it
})
You should look/learn more about node/javascript and asynchronous/event-driven programing.

Serialization of a polymorphic array in node.js

I am looking for a method for serialization of a Javascript object, that contains several other objects of different classes, with function arguments.
Here is a simple test-case:
// Paper class:
function Paper(name) {
this.name = name;
}
Paper.prototype = {
string: function() { return "Paper:"+this.name; }
};
// Book class:
function Book(name) {
this.name = name;
}
Book.prototype = {
string: function() { return "Book:"+this.name; }
};
// Library class:
function Library(name) {
this.items = [];
}
Library.prototype = {
add: function(item) { this.items.push(item); },
string: function () {
var titles = this.items.map(function(item) { return item.string(); });
return titles.join(",");
},
};
///// Define a library:
var lib = new Library();
lib.add(new Paper("MyPaper"));
lib.add(new Book("MyBook"));
assert(lib.string() == "Paper:MyPaper,Book:MyBook");
///// Serialize, de-serialize and compare:
// var libString = serialize(lib);
// var newLib = deserialize(libString);
// assert(newLib.string() == "Paper:MyPaper,Book:MyBook");
NOTE: The main usage of de/serialization (at least in my case) is for moving complex objects to distant computers. For example, I want to build a big Library on my computer, then serialize it, put on a file, send the file to another computer, deserialize it there, and have the exact same Library.
You need to extend JSON semantics. If I were you, I would to something like this:
var protos = {}, //hash of prototypes
base = { //base prototype
toJSON: function () {
var props = {}; //properties to be serialized
for (var prop in this) { //this can be custimized, like taking `attrs` hash or something
if (this.hasOwnProperty(prop)) props[prop] = this[prop];
}
props.$proto = this.$proto; //need to copy this manually since it's not an `own propery`
return props;
}
};
function Paper(name) {
this.name = name;
}
protos.paper = Paper.prototype = Object.create(base);
Paper.prototype.$proto = 'paper';
Paper.prototype.toString = function() {
return 'Paper: ' + this.name;
}
function Book(name) {
this.name = name;
}
protos.book = Book.prototype = Object.create(base);
Book.prototype.$proto = 'book';
Book.prototype.toString = function() {
return 'Book: ' + this.name;
}
function Library(name) {
this.items = [];
}
Library.prototype = {
add: function(item) { this.items.push(item); },
toString: function () {
var titles = this.items.map(function(item) {
return item.toString();
});
return titles.join(',');
},
toJSON: function () {
return this.items.map(function(item) { return item.toJSON()});
}
};
Library.fromJSON = function (json) {
return json.map(function(item) {
var object = Object.create(protos[item.$proto]);
for (var prop in item) object[prop] = item[prop];
return object;
});
};
//test
var lib = new Library();
lib.add(new Paper('MyPaper'));
lib.add(new Book('MyBook'));
console.log(lib.toString());
var json = JSON.stringify(lib.toJSON());
console.log(Library.fromJSON(JSON.parse(json)).toString());
Here is a fiddle: http://jsfiddle.net/cSTT5/
I want to build a big Library on my computer, then serialize it, put on a file, send the file to another computer, deserialize it there, and have the exact same Library.
I've made an npm module named esserializer to solve this problem: save JavaScript class instance values recursively during serialization, in plain JSON format, together with its class name information. Then, during the deserialization stage, esserializer can recursively deserialize object instance, with all types/functions information retained, using the same class definition.
For your scenario, the code is pretty simple. It works if the serialized string is taken to another computer, as long as the same class definition exists on that machine:
const ESSerializer = require('esserializer');
// Paper class:
function Paper(name) {
this.name = name;
}
Paper.prototype = {
string: function() { return "Paper:"+this.name; }
};
Paper.prototype.constructor = Paper; // We need to redefine the constructor of Paper's prototype.
// Book class:
function Book(name) {
this.name = name;
}
Book.prototype = {
string: function() { return "Book:"+this.name; }
};
Book.prototype.constructor = Book;
// Library class:
function Library(name) {
this.items = [];
}
Library.prototype = {
add: function(item) { this.items.push(item); },
string: function () {
var titles = this.items.map(function(item) { return item.string(); });
return titles.join(",");
},
};
Library.prototype.constructor = Library;
///// Define a library:
var lib = new Library();
lib.add(new Paper("MyPaper"));
lib.add(new Book("MyBook"));
// assert(lib.string() == "Paper:MyPaper,Book:MyBook");
var serializedString = ESSerializer.serialize(lib);
// Later, on another machine, deserializedObj is a perfect copy of "lib":
var deserializedObj = ESSerializer.deserialize(serializedString, [Library, Book, Paper]);
console.log(deserializedObj.string()); // Paper:MyPaper,Book:MyBook

Object methods are unavailable after including with require

I'm working through Node.js module, but I'm stuck on how to export a prototype in a way that makes the methods accessible.
For example, take the following code:
var myobj = function(param) {
this.test = 'a test';
return this.param = param;
};
myobj.prototype = {
indexpage: function() {
console.log(this.test);
return console.log(this.param);
}
};
var mo = new myobj('hello world!');
mo.indexpage();
My results are as expected:
a test
hello world!
If I take the same code and place it in another file with module.exports:
somefile.js
var myobj = function(param) {
this.test = 'a test';
return this.param = param;
};
myobj.prototype = {
indexpage: function() {
console.log(this.test);
return console.log(this.param);
}
};
// the only line that is different
module.exports = myobj;
app.js code
var MyObj = require('myobj.js');
var mo = new MyObj('hello world!');
mo.indexpage();
Now I get TypeError: Object #<Object> has no method 'indexpage'
Where am I going wrong? I've been working on this single issue for hours; my basic grasp of javascript isn't helping me figure out this issue any more than searching forums.
You are returning a value from your constructor function.
var myobj = function(param) {
this.test = 'a test';
return this.param = param;
};
should be:
var myobj = function(param) {
this.test = 'a test';
this.param = param;
};
Because of the return, what you are really doing is
var mo = 'hello world!';
mo.indexpage();

How to spy on a property that is not exported

I have a module "sitescollection" like this:
var site = require('./site'); // <- this should be stubbed
var sitesCollection = function(spec) {
var that = {};
that.sites = {};
that.findOrCreateById = function(id) {
if (typeof(that.sites[id]) == "undefined") {
that.sites[id] = site({id: id}); // <- its used here
}
return that.sites[id];
};
return that;
};
module.exports = sitesCollection;
so within sitescollection, site is a module that is not exported. But inside the code, i use it. Now i'm writing jasmine specs for #findOrCreateById().
I want to spec my the findOrCreateBy() function. But i want to stub the site() function, because the spec should be independent from the implementation. Where do i have to create the spyed method on?
var sitescollection = require('../../lib/sitescollection');
describe("#findOrCreateById", function() {
it("should return the site", function() {
var sites = sitescollection();
mysite = { id: "bla" };
// Here i want to stub the site() method inside the sitescollection module.
// spyOn(???,"site").andRetur(mysite);
expect(sites.findOrCreateById(mysite.id)).toEqual(mysite);
});
});
You can achieve this using https: //github.com/thlorenz/proxyquire
var proxyquire = require('proxyquire');
describe("#findOrCreateById", function() {
it("should return the site", function() {
// the path '../../lib/sitescollection' is relative to this test file
var sitesCollection = proxyquire('../../lib/sitescollection', {
// the path './site' is relative to sitescollection, it basically
// should be an exact match for the path passed to require in the
// file you want to test
'./site': function() {
console.log('fake version of "./site" is called');
}
});
// now call your sitesCollection, which is using your fake './site'
var sites = sitesCollection();
var mysite = {
id: "bla"
};
expect(sites.findOrCreateById(mysite.id)).toEqual(mysite);
});
});

Resources