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.

Reply via email to