Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a basic Node JS server which is designed to be used as an API, I've created a log and database module and I've started adding other modules to deal with different request types.

I'm using Express.js and node-mysql

When I visit /v1/group I get the following error -

TypeError: Cannot read property 'database' of undefined
    at Group.getAll (C:codejavascript
odeapiapiv1groups.js:12:23)
    at callbacks (C:codejavascript
odeapi
ode_modulesexpresslib
outerindex.js:161:37) ...

So I guess after recieving a request and calling group.getAll() that this is undefined but I don't understand why, is there a way to set this or have I structured my application all wrong?

sever.js

"use strict";

var Express = require('express');
var Log = require('./database/log');
var Database = require('./database/database');
var dbConfig = require('./dbconfig.json');

var Group = require('./api/v1/groups');


//Init express
var app = new Express();

//Init log and database
var log = new Log();
var database = new Database(dbConfig, log);

var initCallback = function() {
    //Init routes
    var group = new Group(database, log);

    //Group routes
    app.get('/v1/group', group.getAll);
    app.get('/v1/group/:id', group.getByID);

    app.listen(3000);
    log.logMessage("INFO", "Listening on port 3000");
};

//Test database connection
database.getConnection(function(err, connection) {
    if (err) {
        log.logMessage("FATAL", "Error connecting to database, check database is running and the dbconfig.json file is present and correct.");
        process.exit(1);
    }
    connection.end();

    initCallback();
});

database.js

"use strict";

var mysql = require('mysql');


var Database = function(dbConfig, log) {
    this.connected = false;
    this.log = log;

    this.log.logMessage("INFO", "Connecting to database with: Host - " + dbConfig.dbhost + ", Database port - " + dbConfig.dbport + ", Database name - " + dbConfig.dbname + ", User " + dbConfig.dbuser + ", Password length - " + dbConfig.dbpass.length);

    this.pool  = mysql.createPool({
        host : dbConfig.dbhost,
        user : dbConfig.dbuser,
        port: dbConfig.dbport,
        password : dbConfig.dbpass,
        database: dbConfig.dbname
    });
};

Database.prototype.getConnection = function() {
    var args = arguments;
    return this.pool.getConnection.apply(this.pool, arguments);
};

module.exports = Database;

groups.js

"use strict";

var Group = function(database, log) {
    this.database = database;
    this.log = log;
};

Group.prototype.getAll = function(req, res) {
    console.log(this); // --> undefined

    var query = 'SELECT * FROM invgroups WHERE published = 1';

    this.database.getConnection(function(err, connection) { // --> error line
        if (err) { res.send(500, "Database error"); }

        connection.query(query, function(err, results) {
            if (err) { res.send(500, "Database error"); }
            res.send(results);
        });

        connection.end();
    });

};


Group.prototype.getByID = function(req, res) {
    console.log(this);
    res.send({name: "Group Item 1"});
};

module.exports = Group;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
106 views
Welcome To Ask or Share your Answers For Others

1 Answer

You need to properly bind the function.

app.get('/v1/group', group.getAll);

only passes the getAll function as a handler, but the function itself has no concept of this. this is decided based on the context that is bound, or based on how the function is called. This blog post is useful for understanding how function context works.

app.get('/v1/group', group.getAll.bind(group));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...