Search code examples
javascriptnode.jsexpressmongoskindhtmlx-scheduler

TypeError: Cannot read property 'apply' of undefined at EventEmitter


I'm building a node js application with the DHTMLX Scheduler as one of the pages. However, whenver the page loads, the app crashes and I get the following error:

TypeError: Cannot read property 'apply' of undefined at EventEmitter.(/node_modules/mongoskin/lib/collection.js:52:21))

Here is the module the error references:

  SkinCollection.prototype._open = function(callback) {
    var collection_args = this._collection_args.concat([callback]);
    this._skin_db.open(function(err, db) {
        if(err) return callback(err);
        db.collection.apply(db, collection_args);
    });
  }

And here is the portion of my app.js that is causing the error, when I don't include this code the calendar doesn't crash the app but I have no way of sending the data to my MongoDB atlas cluster.

app.js

    app.use(express.static(path.join(__dirname, 'public')));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

    app.get('/init', function(req, res){
        db.event.insert({ 
            text:"My test event A", 
            start_date: new Date(2018,8,1),
            end_date:   new Date(2018,8,5)
        });
        db.event.insert({ 
            text:"My test event B", 
            start_date: new Date(2018,8,19),
            end_date:   new Date(2018,8,24)
        });
        db.event.insert({ 
            text:"Morning event", 
            start_date: new Date(2018,8,4,4,0),
            end_date:   new Date(2018,8,4,14,0)
        });
        db.event.insert({ 
            text:"One more test event", 
            start_date: new Date(2018,8,3),
            end_date:   new Date(2018,8,8),
            color: "#DD8616"
        });

        res.send("Test events were added to the database")
    });


    app.get('/data', function(req, res){
        db.event.find().toArray(function(err, data){
            //set id property for all records
            console.log(err);
            for (var i = 0; i < data.length; i++)
                data[i].id = data[i]._id;

            //output response
            res.send(data);
        });
    });


    app.post('/data', function(req, res){
        var data = req.body;
        var mode = data["!nativeeditor_status"];
        var sid = data.id;
        var tid = sid;

        delete data.id;
        delete data.gr_id;
        delete data["!nativeeditor_status"];


        function update_response(err, result){
            if (err)
                mode = "error";
            else if (mode == "inserted")
                tid = data._id;

            res.setHeader("Content-Type","application/json");
            res.send({action: mode, sid: sid, tid: tid});
        }

        if (mode == "updated")
            db.event.updateById( sid, data, update_response);
        else if (mode == "inserted")
            db.event.insert(data, update_response);
        else if (mode == "deleted")
            db.event.removeById( sid, update_response);
        else
            res.send("Not supported operation");
    });

I've only been learning javascript for the past week and am very new to coding. I don't understand why this error is occuring. When I run the Scheduler app as a stand alone feature it works flawlessly. Only when I try to implement it in my website does it throw this error.


Solution

  • Update: Correct Answer

    This question is a duplicate of: MongoSkin "Cannot read property 'apply' of undefined"

    Mongoskin only supports MongoDB 2.x, this error happens when using MondoDB 3.x.

    Original (Incorrect) Answer

    Pretty new to MongoDB myself, but I'm pretty sure the problem is that you need to replace collection with the actual name of the table on this line:

    db.collection.apply(db, collection_args);
    

    So for example, if name of the table/collection was skin, the line would become:

    db.skin.apply(db, collection_args);
    

    (Notice how when app.j executes a db operation on the events table, it is calling db.event.insert(), etc...)