1

I am trying to set a response message to the user, but when I do I get an error. (Cannot read property 'message' of undefined) This is the code that doesn't work:

server.js

const server = express();
let  App =  require('./controllers/app');
App = new App();
server.use('/', App.router);

http.createServer(server).listen(8080);

app.js

class App {
    constructor () {
        this.message = '';
    } 

    router (request, response) {
        if (request.url === '/register') {
            response.render('register.ejs', {
                url: request.url,
                header: headBase + 'register',
                message: this.message, //  This is where the error is triggered
                user: username
            });
            this.message = '';
        }
    }
}

Anywhere i try to set or read this.message in the router method i get the error.

Alpus96
  • 28
  • 4

3 Answers3

1

The problem is here

let  App =  require('./controllers/app');
App = new App();
server.use('/', App.router);

Before I dive into the real issue, I'll also mention that overriding App with an instance of App is a bad idea, so I'm going to rewrite this as:

const App = require('./controllser/app')
const app = new App();
server.use('/', app.router);

Now it's more clear that what you're passing in is the method reference from the instance of App.

The problem is that you're passing the function, but the function is not bound to app in any way. There are a variety of ways you can fix this.

The simplest is to pass app.router.bind(app) which wraps app.router in a function that calls app.router in the context of app:

server.use('/', app.router.bind(app))

The next simplest (as you're using ES2015 features) is to wrap the function in a lambda:

server.use('/', (...args) => app.router(...args))
zzzzBov
  • 157,699
  • 47
  • 307
  • 349
0

I managed to get around it. I just changed this.message to App.message in the router method.

class App {
    constructor () {
        this.message = '';
    } 

    router (request, response) {
        if (request.url === '/register') {
            response.render('register.ejs', {
                url: request.url,
                header: headBase + 'register',
                message: App.message,
                user: username
            });
            App.message = '';
        }
    }
}
Alpus96
  • 28
  • 4
0

An alternative to zzzzBov solution can be to bind the method in the constructor:

class App {
    constructor () {
        this.message = '';
        this.router = this.router.bind(this)
    } 

    router (request, response) {
        if (request.url === '/register') {
            response.render('register.ejs', {
                url: request.url,
                header: headBase + 'register',
                message: this.message,
                user: username
            });
            this.message = '';
        }
    }
}
zied hajsalah
  • 486
  • 8
  • 15