user9366125
user9366125

Reputation:

Typescript cannot read property of undefined

TypeError: Cannot read property 'ghNewPrMethod' of undefined

When I try send a webhook POST to my Typescript application, I get the above error.

I have the following controller

import { GhStatusSchema } from '../models/gh-status.model';
import { Request, Response } from 'express';

import * as crypto from 'crypto';
import { Helpers } from '../helpers';
import { GhNewPrMethod } from '../methods/gh-new-pr.method';

import { GitHubConfig } from '../../config/github';

const secret: string = GitHubConfig.secret;

export class GhNewPrController {
  public helpers: Helpers = new Helpers();
  public ghNewPrMethod = new GhNewPrMethod();

  public post(req: Request, res: Response) {
    console.log(111);
    this.ghNewPrMethod.slackMessage(req.body, req.get('x-github-delivery'))
  } 
}

it seems there is an issue with this.ghNewPrMethod.slackMess and this is undefined.

** gh-new-pr.method.ts**

import * as Slack from 'slack-node';

import { GhMessageSchema } from '../models/gh-new-pr.model';
import { SlackConfig } from '../../config/slack';
import { UsersConfig } from '../../config/users';
import { Helpers } from '../helpers';

export class GhNewPrMethod {
  helpers: Helpers = new Helpers();

  public findSavedPR(id) {
    return new Promise((resolve, reject) => {
      GhMessageSchema.find({
        pull_request: id
      }, (err, message) => {
        if (err || message.length === 0) {
          reject(err);
        }
        resolve(message);
      });
    });
  }

  public slackMessage(payload, header) {
    console.log(payload);
  }
}

The reason I'm using another file is break down my controller into smaller functions in another file so some can be re-usable and makes the controller look much cleaner.

Could someone help me

edit:

route.ts

import { Request, Response, NextFunction } from "express";
import { GhNewPrController } from '../controllers/gh-new-pr.controller';

export class Routes {

  public ghNewPrController: GhNewPrController = new GhNewPrController()

  public routes(app): void {

    app.route('/github')
      .post(this.ghNewPrController.post)

  }
}

Upvotes: 0

Views: 4012

Answers (1)

benshabatnoam
benshabatnoam

Reputation: 7680

You're having a scoping issue. To fix this use bind function as follows:

app.route('/github').post(this.ghNewPrController.post.bind(this.ghNewPrController))

From developer.mozilla: "The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called."

DEMO

Upvotes: 2

Related Questions