wokoro douye samuel
wokoro douye samuel

Reputation: 2374

Variable becomes undefined when access in a class method

I defined a class variable in a constructor which holds a reference to an imported class instance.

However, when I try to access the variable in my class methods I keep getting undefined for that variable.

Exported class

import models from '../../database/models'

const {User} = models;

class UserRepository {
  constructor(){
    this.model = User;
  }

 async create({firstname, lastname, email, isadmin, password}){
  return await this.model.create({firstname, lastname, email, isadmin, password})
  }
}

export default new UserRepository();

Class using the exported class

import repository from './repository';
import { sendSuccessMessage } from '../../utils'

class UserController {
  constructor() {
    this.model = repository;
  }

  async createUser({ body }, res, next) {
    try {
      const result = await this.model.create(body);
      sendSuccessMessage(res, 200, result);
    } catch( e ){
      next(e)
    }
  }
}

export default new UserController();

However, using the variable repository directory in createUser as specified below:

const result = await repository.create(body);

works as expected.

Current call chain

// routes.js file
import controller from './controller'

export default [
  {
    path: '/signup',
    method: 'post',
    handlers: [controller.createUser] // createUser from class UserController
  }
]


// utitlity.js file
export const routesLoader = (routes, router) => {
 for (const route of routes) {
   const { path, handlers, method } = route;
   (router)[method](path, handlers);
 }
};

// app.js file
import express from 'express';
import routes from './routes.js';
import { routesLoader } from './utils';

const router = express.Router();

routesLoader(routes, router);

// server.js file
import http from 'http';
import app from './app';

const { PORT = 3000 } = process.env;

const server = http.createServer(app);

server.listen(PORT, () => {
  console.log(`server listening on localhost: ${PORT}`);
});

Error

TypeError: Cannot read property 'create' of undefined
at _callee$ (C:\Users\MYPC\Downloads\moch-shop-api-master\components\user/controller.js:16:39)
at tryCatch (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\regenerator-runtime\runtime.js:45:40)
at Generator.invoke [as _invoke] (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\regenerator-runtime\runtime.js:271:22)
at Generator.prototype.<computed> [as next] (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\regenerator-runtime\runtime.js:97:21)
at asyncGeneratorStep (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\@babel\runtime\helpers\asyncToGenerator.js:3:24)
at _next (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\@babel\runtime\helpers\asyncToGenerator.js:25:9)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\@babel\runtime\helpers\asyncToGenerator.js:32:7
at new Promise (<anonymous>)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\@babel\runtime\helpers\asyncToGenerator.js:21:12
at createUser (C:\Users\MYPC\Downloads\moch-shop-api-master\components\user\controller.js:70:28)
at Layer.handle [as handle_request] (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\index.js:275:10)
at cors (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:188:7)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:224:17
at originCallback (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:214:15)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:219:13
at optionsCallback (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:199:9)

Technologies used

@babel/node: "^7.8.4"
terminal: git bash
Os: windows

Upvotes: 1

Views: 1008

Answers (3)

pspi
pspi

Reputation: 11927

How is UserController.createUser called? Sounds like its this is not set up correctly. Let's say we initialized the class like this:

const userController = new UserController();

Then, one source for missing this can be if you only pass an exact reference to the method

setImmediate(userController.createUser);

instead of a way that retains this:

setImmediate(() => {
   userController.createUser()
});

In other words, you want to invocate the method using dot notation and involve the class instance.

Upvotes: 1

Deep Kakkar
Deep Kakkar

Reputation: 6307

First, you need to import UserRepository properly before its utilization.

import UserRepository from 'path to UserRepository class';

then Use self in your function as follows:

async createUser({ body }, res, next) {
 const self = this;
 try {
   const result = await self.model.create(body);
   sendSuccessMessage(res, 200, result);
 } catch( e ){
   next(e)
 }
}

I think better to use self as compared to this in your createUser() function.

Upvotes: 0

adz5A
adz5A

Reputation: 2032

Your method create is an instance method. It needs to be static for this to work

Upvotes: 0

Related Questions