2

Hello I'm trying to create an application using express and es6 classes, but every time the class method is called this is undefined.

UserController.js

export class UserController {

    constructor() {
        console.log('Class Constructed');
        this.service = new UserService();
    }

    create(req, res, next) {
        console.log('console', this);
        this.service.create(req.body).then((user) => {
            res.send(user);
        });
    }
}

route.js

import { Router } from 'express';
const router = Router();

router.route('/user/create')
    .post(new UserController().create);

I noticed that when I execute npm run dev, I got the console in the controller constructor, but when I call the '/user/create' from postman. I got TypeError: Cannot read property 'service' of undefined.

Did I miss something? or is this kind of approach possible?

It would be great if someone can help me with this.

Thanks a lot.

blitzen12
  • 1,350
  • 3
  • 24
  • 33

2 Answers2

0

You have to store the recent created UserControoller instance, then call to its create function, so this is inferred under the scenes.

router.route(`/user/create`, (req, res, next) => {
    const controller = new UserController();
    controller.create(req, res, next);
});

Or even call the create function without storing the instance.

router.route(`/user/create`, (req, res, next) => {
    new UserController().create(req, res, next);
});

By passing the create function without calling yourself, the function will be invoked by express at some point and express won't be able to bind the this property of the prototype, since it has no reference to the instance.

Hope it helps.

VRoxa
  • 973
  • 6
  • 25
0

Perhaps you need to bind create function to class

 constructor() {
        console.log('Class Constructed');
        this.service = new UserService();
        this.create = this.create.bind(this);
    }

Example

class UserService {
  create(data) {
    return Promise.resolve({})
  }
}

class UserController {

  constructor() {
    console.log('Class Constructed');
    this.service = new UserService();
    this.create = this.create.bind(this);
  }

  create(req, res, next) {
    console.log('console', this);
    this.service.create(req.body).then((user) => {
      res.send(user);
    });
  }
}

function post(callback) {
  callback({
    body: {}
  }, {
    send: () => {}
  }, () => {})
}

post(new UserController().create);
Józef Podlecki
  • 10,453
  • 5
  • 24
  • 50