2013-03-24 2 views
8

Ich habe eine grundlegende Node JS Server, der als API verwendet werden soll, habe ich ein Protokoll und Datenbank-Modul erstellt und ich habe begonnen Hinzufügen anderer Module, um mit verschiedenen Anfragetypen umzugehen.Express JS 'dies' undefiniert nach dem routing mit app.get (..)

Ich verwende Express.js und Knoten-mysql

Wenn ich besuchen /v1/group ich die folgende Fehlermeldung erhalten -

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) ... 

Also ich denke, nach einer Anfrage recieving und ruft group.getAll() dass this undefiniert aber ich verstehe nicht warum, gibt es eine Möglichkeit this einzustellen oder habe ich meine Anwendung falsch strukturiert?

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; 

Antwort

20

Sie müssen die Funktion richtig binden.

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

nur übergibt die getAll Funktion als Handler, aber die Funktion selbst hat kein Konzept von this. this wird basierend auf dem gebundenen Kontext oder basierend auf dem Aufruf der Funktion entschieden. This blog post ist nützlich, um zu verstehen, wie Funktionskontext funktioniert.

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

Arbeitete perfekt, vielen Dank, bin ich die Strukturierung der richtige Weg oder sollte ich es anders gehen? – Sam

+0

@Sam Das ist eine schwierigere Frage. Ich würde sagen, nur nachforschen, einige Blogposts von anderen Leuten finden, die APIs geschrieben haben und sehen, was am besten funktioniert. Ich bin sicher, dass es einige Projekte auf GitHub gibt, die Sie finden können. Ich habe nicht viel API Arbeit getan, also kann ich nicht viel sagen. – loganfsmyth

+0

Ich habe ein wenig Nachforschungen angestellt, aber jeder scheint eine etwas andere Art zu haben, Dinge in Node zu tun. Ich schätze, ich werde diesen Weg gehen und sehen, was passiert, solange es nicht irgendwas mit meiner Implementierung zu tun hat, danke sehr, – Sam