6

This class is used to extend all the controllers inside my expressjs application:

import response from '../utils/responseParser.js';

const APISLUG = '/api/v1/';

export default class BaseController {

  constructor(name, app, model){
    this.model = model;
    this.app = app;
    this.name = name;
    console.log(model);
    this.register();
  }

  register() {
    this.app.get(APISLUG + this.name, this.all);
  }
  /*
  Retrive all records
  */
  all(req, res, next) {
    this.model.all(req.body, (err, data) => {
      if(err) return res.json(response.replyError(data));
      return res.json(response.reply(data));
    });
  }
}

As you can see I have made a " register" method to automatically set-up all the basic routes.

I get a error unable to read property " model " of undefined " on this line:

this.app.get(APISLUG + this.name, this.all);

I believe this is due to the fact that the scope get lost when I pass the function as parameter. How can I solve this?

xpt
  • 13,224
  • 19
  • 76
  • 149
Wanny Miarelli
  • 561
  • 2
  • 13
  • 28

2 Answers2

13

Use bind method to bind the scope, like this

this.app.get(APISLUG + this.name, this.all.bind(this));
Ammar Hasan
  • 2,238
  • 13
  • 20
4

You can set an arrow function as a property on the class. Arrow functions lexically binds the this value (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions).

In your example:

export default class BaseController {
  ...
  all = (req, res, next) => { // This is the only line that changed
    ...
  }
}

Note that arrow functions on classes are not standard ES6 syntax, but will probably come with ES7 (some notes about that in comments here: https://stackoverflow.com/a/31362350/2054731). You may need to configure your project to be able to use this and/or other ES7 features.

Community
  • 1
  • 1
ArneHugo
  • 4,867
  • 1
  • 21
  • 39