Hello! Thank you for help, it works! Function enclosures and "this" are not good friends, I knew it, but forgot about this in NodeJS :) Thank you!!!
On Sunday, March 16, 2014 4:10:23 PM UTC+1, ryandesign wrote: > > On Mar 16, 2014, at 09:18, Evgeny Nepomnyashchiy > <[email protected]<javascript:>> > wrote: > > > I'm learning programming on NodeJS, it's my first back-end experience. > > Welcome! > > > I have a small problem. I created class (module) Database, which manages > connection and queries to a database, here is implementation: > > > > var mysql = require('mysql'); > > > > function Database() { > > this.connection = null; > > this.connected = false; > > } > > > > Database.prototype.connect = function (config, callback) { > > console.log('[Database] Connecting...'); > > > > this.connection = mysql.createConnection(config); > > this.connection.connect(function (err) { > > if (err == null) { > > this.connected = true; > > } > > > > console.log('connect: this.connected = ' + this.connected); > > console.log('[Database] Connected'); > > > > callback(err); > > }); > > } > > > > Database.prototype.makeQuery = function (query, callback) { > > console.log('makeQuery: this.connection = ' + this.connection); > > console.log('makeQuery: this.connected = ' + this.connected); > > > > if (this.connected == false) { > > return callback(new Error('[Database] You cannot make queries > before connection')); > > } > > console.log('[Database] Making query: %s', query.sql()); > > > > // making query to the database > > } > > > > exports.Database = Database; > > > > As you can see, here I store connected property. If I try to make query > before successful connection I will get error [Database] You cannot make > queries before connection. But it doesn't work, it shows me this error > always, because connected property becomes false, here is example of usage > this module outside: > > > > var config = require('./config.json'); > > var query = require('./modules/database/query'); > > > > console.log('Server Started'); > > > > var database = new (require('./modules/database')).Database(); > > database.connect(config.database, function (err) { > > console.log("connect handler"); > > > > if (err) { > > throw err; > > } > > > > var query = new query.Query(); > > // some actions with query, doesn't matter > > > > database.makeQuery(categoriesNameQuery, function (err, result) { > > if (err) { > > throw err; > > } > > > > // working with the result > > }); > > }); > > > > In console I get the following: > > > > /usr/local/bin/node database_test.js > > Server Started > > [Database] Connecting... > > connect: this.connected = true > > [Database] Connected > > connect handler > > makeQuery: this.connection = [object Object] > > makeQuery: this.connected = false > > > > Error: [Database] You cannot make queries before connection > > at Database.makeQuery (/modules/database/index.js:35:25) > > at /database_test.js:30:14 > > ... > > > > I can't understand, why property connected is true after connection, and > false when I make a query. But property connection works fine! Maybe > enclosures in NodeJS work by other way. > > You’re running into a fun quirk of “this”. This is not unique to node; > it’s just how the JavaScript language works, and you’d have the some > problem in a browser. The problem is that at the point where you’re setting > this.connected = true, “this” isn’t what you think it is, because the code > in question is in a function that’s called back later (whenever > this.connection.connect() has finished connecting); at that later time, > “this” no longer points to the instance of the Database class, but instead > to the global object. > > The pattern usually used to combat this quirk is to save the value of > “this” in a new variable, often called “that” or “self”, and then use that > instead of “this”: > > > Database.prototype.connect = function (config, callback) { > console.log('[Database] Connecting…’); > > var that = this; > // Here you could use “this” or “that”; it makes no difference: > this.connection = mysql.createConnection(config); > this.connection.connect(function (err) { > // In here, you have to use “that”; “this” points to the global > object, not the class instance: > if (err == null) { > that.connected = true; > } > > console.log('connect: that.connected = ' + that.connected); > console.log('[Database] Connected'); > > callback(err); > }); > } > > > Some more reading if you’re interested: > > > http://stackoverflow.com/questions/4886632/what-does-var-that-this-mean-in-javascript > > > > -- -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en --- You received this message because you are subscribed to the Google Groups "nodejs" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
