Francisco
Francisco

Reputation: 450

Error instantiating properties of an exported class

I'm trying to instantiate an exported class, but I'm getting the following error:

TypeError: Cannot set property '_db' of undefined

How I am creating and exporting the class:

const mongodb = require('mongodb').MongoClient
const url = 'mongodb://localhost/via'
const collection = 'images'

module.exports = class DB {
    constructor() {
        mongodb.connect(url, function(err, db) {
            if (err) throw err

            this._db = db.db('via') //Error line

            this._db.createCollection(collection, function(err, res) {
                if (err) throw err
                console.log(`Collection ${collection} created successfully.`)
            })
        })
    }
}

How I am instantiating:

const db = require('../db/images')
let database = new db();

I've tried creating the variable before using it, but to no avail. What am I doing wrong?

Upvotes: 1

Views: 38

Answers (1)

Keith
Keith

Reputation: 24191

The problem here is that your constructor where your calling mongodb.connect your using a normal function callback -> function(err, db) this means anything inside the function this won't be pointing to your class.

One simple solution to this is use the arrow function, replace function(err, db) { with (err, db) => {

Personally I'm not a big fan of arrow functions, in some respects I see it like the with statement, it's easy to loose context. So another way, that works with arrow function & normal functions is to capture scope.

For example ->

module.exports = class DB {
    constructor() {
        const thisDB = this;
        mongodb.connect(url, function(err, db) {
            if (err) throw err

            thisDB._db = db.db('via') //Error line

            thisDB._db.createCollection(collection, function(err, res) {
                if (err) throw err;
                //bonus, thisDB will work here too.
                console.log(`Collection ${collection} created successfully.`)
            })
        })
    }
}

Above it's obvious what thisDB points too, and when doing even deeper level callbacks it will still be valid as shown above where I've mentioned bonus, thisDB will work here too

Upvotes: 2

Related Questions