简体   繁体   中英

Why am I getting undefined instance in node.js class?

I am newbie in node.js. I am trying to define a constructor for node.js class which basically fetches data from mongo db. The code for same is as follows

var MongoClient = require('mongodb').MongoClient,
    Server = require('mongodb').Server;

var ObjectID = require('mongodb').ObjectID;
var mongoHost = 'localHost';
var mongoPort = 27017;

CollectionDriver = function(db) {
    this.db = db;
    console.log("Collection drive has been set");
};

CollectionDriver = function() {
    var mongoClient = new MongoClient(new Server(mongoHost, mongoPort));
    mongoClient.open(function(err, mongoClient) {
        if (!mongoClient || err) {
            console.error("Error! Exiting... Must start MongoDB first");
            process.exit(1);
        }
        var db1 = mongoClient.db("Quiz");
        this.db = db1;
        console.log("Set Collection Driver by default");
    });
};

CollectionDriver.prototype.getCollection = function(collectionName, callback) {
    this.db.collection(collectionName, function(error, the_collection) {
        if (error) callback(error);
        else callback(null, the_collection);
    });
};
//find all objects for a collection
CollectionDriver.prototype.findAll = function(collectionName, obj, callback) {
    this.getCollection(collectionName, function(error, the_collection) {
        if (error) callback(error);
        else {
            the_collection.find(obj).toArray(function(error, results) {
                if (error) callback(error);
                else {
                    console.dir(results);
                    callback(null, results);
                }

            });
        }
    });
};

I am trying to use this in other class as follows:

CollectionDriver = require('./collectionDriver').CollectionDriver;
var collectionDriver = new CollectionDriver(db);
OtherClassName.prototype.find = function(credentials, callback) {

    collectionDriver.findAll("user_groups", credentials, function(error, results) {

        if (!error) {
            // Do something
        }
    });

    // ...

Whenever I try to access find method of Otherclass it says db variable of above class(ie ConnectionDriver) is undefined. However I could see ConnectionDriver constructor is getting executed correctly and connection to db is opened correctly and this.db=db1 is also gettining executed.Am I doing something wrong? Any help would be appreciated

After banging my head and investing(inwasting) a whole day. I realised the issue. Actually mongoClient.open() call is an asyncronous call and i return the CollectionDriver object even before opening db/getting db instance.

I solved this problem by moving opening of db call outside constructor and setting instance db . The modified code is as follows :

var db = null;
var mongoClient = new MongoClient(new Server(mongoHost, mongoPort));
mongoClient.open(function(err, mongoClient) {
    if (!mongoClient || err) {
        console.error("Error! Exiting... Must start MongoDB first");
        process.exit(1);
    }
    db = mongoClient.db("Quiz");

});

CollectionDriver = function() {
console.log("Set Collection Driver by default");
};

The above code seem to work , however when I assign db instance to this.db rather than explicitly declaring a variable as done above , I get same undefined/null error(when i initialise db variable to null). Any thoughts why this behavior ??

This is already answered but I believe the correct answer for this is, this gets redefined in function calls. Inside the callback function to open, this now points to the function. The way around this is to use ES6 arrow functions, if you're on node 4+.

collectionDriver = function() {
var mongoClient = new MongoClient(new Server(mongoHost, mongoPort));
mongoClient.open((err, mongoClient) => {
    if (!mongoClient || err) {
        console.error("Error! Exiting... Must start MongoDB first");
        process.exit(1);
    }
    var db1 = mongoClient.db("Quiz");
    this.db = db1;
    console.log("Set Collection Driver by default");
});

Note: the function (err, mongoClient) { is changed to (err, mongoClient) => {

this then behaves as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM