Home > Mobile >  (Express, Node, Typescript, REST API) How can I import a function from the service to the controller
(Express, Node, Typescript, REST API) How can I import a function from the service to the controller

Time:04-05

How should i import loginMember in Controller? I am developing as a REST API and now I need to use code in a different file location. I am having a error in controller. When i am calling loginMember.(Cannot find name 'loginMember'.ts(2304))

SERVICE

import MembersModel from '../models/MembersModel';
import BaseService from './BaseService';
import { createPasswordToHash } from '../scripts/utils/auth';
class MembersService extends BaseService {  
  constructor() {
    super(MembersModel);
  }

  // loginMember
  loginMember = async (email: any, password: any) => {
    return new Promise(async (resolve, reject) => {
      try {
        let data = await this.BaseModel.findOne({
          email: email,
          password: createPasswordToHash(password),
        });
        return resolve(data);
      } catch (error) {
        return reject(error);
      }
    });
  };
  
}

export default MembersService;

CONTROLLER

import BaseController from './BaseController';
import MembersService from '../services/MembersService';
import ApiError from '../errors/ApiError';
import { NextFunction, Request, Response } from 'express';
import { createPasswordToHash, generateAccessToken } from '../scripts/utils/auth';
import httpStatus from 'http-status';

class MembersController extends BaseController {
  constructor(membersService: MembersService) {
    super(membersService);    
  }

login = (req: Request, res: Response, next: NextFunction) => {
  MembersService.loginMember(req.body)
    .then((response: any) => {
      if (response) {
        const member = {
          ...response.toObject(),
          accessToken: generateAccessToken(response.toObject()),
        };
        delete member.password;
        delete member.createdAt;
        delete member.updatedAt;
        return res.status(httpStatus.OK).send(member);
      }
      return res.status(httpStatus.UNAUTHORIZED).send({ error: 'Invalid email or password' });
    })
    .catch((err: { message: string }) => {
      return next(
        new ApiError(err.message, httpStatus.UNAUTHORIZED, 'login', req.headers['user-agent']?.toString() || 'Unknown')
      );
    });
};
  
}
export default new MembersController(new MembersService());

Now i am gettig new error: "Property 'loginMember' does not exist on type 'typeof MembersService'.ts(2339)"

CodePudding user response:

You're trying to call loginMember as a static method, but it's not defined as one. You'll have to use an instance of MembersService to use the method. Since your MembersController is already being initialized with a MembersService instance, you may just want to have a membersService property on the MembersController. Also, the loginMember method takes an email and a password, so you'll have to pass those arguments explicitly instead of just passing the request body. (I'm not sure where the email and password are in the request body though, so I can't help you there.) So with those changes, it would look like:

class MembersController extends BaseController {
  private membersService: MembersService;

  constructor(membersService: MembersService) {
    super(membersService);
    this.membersService = membersService;
  }

login = (req: Request, res: Response, next: NextFunction) => {
  this.membersService.loginMember(email, password) // <- Get these from the request
    .then((response: any) => {
      if (response) {
        const member = {
          ...response.toObject(),
          accessToken: generateAccessToken(response.toObject()),
        };
        delete member.password;
        delete member.createdAt;
        delete member.updatedAt;
        return res.status(httpStatus.OK).send(member);
      }
      return res.status(httpStatus.UNAUTHORIZED).send({ error: 'Invalid email or password' });
    })
    .catch((err: { message: string }) => {
      return next(
        new ApiError(err.message, httpStatus.UNAUTHORIZED, 'login', req.headers['user-agent']?.toString() || 'Unknown')
      );
    });
};

One other code style suggestion would be to use async await instead of .then in the login method. Also, the Promise wrapping in the loginMember method looks unnecessary, and using an async function as the argument is an antipattern. The following should get the job done while avoiding those pitfalls:

  loginMember = (email: any, password: any): Promise<Response> => {
    return this.BaseModel.findOne({
      email: email,
      password: createPasswordToHash(password),
    });
  };
  • Related