2013-03-24 2 views
8

У меня есть базовый Node JS-сервер, который предназначен для использования в качестве API, я создал модуль журнала и базы данных, и я начал добавление других модулей для обработки разных типов запросов.Express JS 'this' undefined после маршрутизации с app.get (..)

Я использую Express.js и узел-MySQL

Когда я посещаю /v1/group я получаю следующее сообщение об ошибке -

TypeError: Cannot read property 'database' of undefined 
    at Group.getAll (C:\code\javascript\node\api\api\v1\groups.js:12:23) 
    at callbacks (C:\code\javascript\node\api\node_modules\express\lib\router\index.js:161:37) ... 

Так я думаю после получать запрос и вызова group.getAll() что this не определен но я не понимаю, почему, есть ли способ установить this или я структурировал свое приложение, все неправильно?

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; 

ответ

20

Вам необходимо правильно связать функцию.

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

проходит только функцию getAll в качестве обработчика, но сама функция не имеет понятия о this. this определяется на основе связанного контекста или основывается на том, как вызывается функция. This blog post полезен для понимания того, как работает контекст функции.

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

Работал отлично, спасибо большое, я правильно структурирую это, или я должен идти об этом по-другому? – Sam

+0

@Sam Это более сложный вопрос. Я бы сказал, просто исследования, найти некоторые сообщения в блоге от других людей, которые написали API и посмотреть, что работает лучше всего. Я уверен, что есть какие-то проекты по github, которые вы можете найти. Я не много работал API, поэтому не могу сказать много. – loganfsmyth

+0

Я провел довольно немного исследований, но у всех, кажется, есть несколько иной способ сделать что-то в узле. Думаю, я пойду так и посмотрю, что произойдет, если в моей реализации нет чего-то нелепого, спасибо большое – Sam