Harts
Harts

Reputation: 4093

How to setup variable in nodejs typescript

How come running this on postman localhost:3000/api/watson/get-test

it gives error -> TypeError: Cannot read property 'myTest' of undefined

import {Router, Request, Response, NextFunction} from 'express';

export class IbmWatsonRouter {
  router: Router;
  mytest: any;

  /**
   * Initialize the Router
   */
  constructor() {
    this.mytest = new Service();
    this.router = Router();
    this.init();   

  }

  /**
   * Get
   */
  public getTest(req: Request, res: Response, next: NextFunction) {            
    res.send(this.mytest.getSomething());    
  }

  /**
   * POST Analyze-Text.
   */
  public analyzeText(req: Request, res: Response, next: NextFunction) {
    this.mytest.setSomething('aaaa');
    res.send('successfully analyze text');    
  }

  /**
   * Take each handler, and attach to one of the Express.Router's
   * endpoints.
   */
  init() {
    this.router.get('/get-test', this.getTest);
    this.router.post('/analyze-text', this.analyzeText);
  }

}

Upvotes: 0

Views: 256

Answers (3)

Hosar
Hosar

Reputation: 5292

You need to bind the context.
Try with something like this:

this.router.get('/get-test', this.getTest.bind(this));


The complete example:

import {Router, Request, Response, NextFunction} from 'express';
import express from 'express';

class Service {
    getSomething() {
        return 'Hola';
    }
}

class IbmWatsonRouter {
  router = null;
  mytest = null;
  app = null;

  /**
   * Initialize the Router
   */
  constructor() {
    this.mytest = new Service();
    this.router = Router();
    this.init();   

  }

  /**
   * Get
   */
  getTest(req, res, next) {            
      //res.send('ok');
    res.send(this.mytest.getSomething());    
  }

  /**
   * POST Analyze-Text.
   */
  analyzeText(req, res, next) {
    this.mytest.setSomething('aaaa');
    res.send('successfully analyze text');    
  }

  /**
   * Take each handler, and attach to one of the Express.Router's
   * endpoints.
   */
  init() {
    this.router.get('/get-test', this.getTest.bind(this));
    this.router.post('/analyze-text', this.analyzeText);
    this.app = express();
    this.app.use(this.router);
    this.app.listen(5200, () => {
        console.log('App listening on 5200');
        
    });    
  }

}

const r = new IbmWatsonRouter;

Upvotes: 0

galkin
galkin

Reputation: 5519

Try to separate router, service and controller. Also, any function in a controller should be static.

Router

import {Router} from 'express';
import {IbmWatsonController} from './controllers/ibmwatson';
export const router = Router();
router.get('/get-test', IbmWatsonController.getTest);
router.post('/analyze-text', IbmWatsonController.analyzeText);

Controller

import {Request, Response, NextFunction} from 'express';
import {Service} from '../services/service';
const serviceInstance = new Service();
export class IbmWatsonController {
  public static getTest(req: Request, res: Response, next: NextFunction) {            
    res.send(serviceInstance.example);    
  }

  public static analyzeText(req: Request, res: Response, next: NextFunction)   {
    serviceInstance.example = 'aaaa';
    res.send('successfully analyze text');    
  }
}

Service

//@todo: rewrite with stateless solution
export class Service {
   privat mytest = 'aaaaa';
   get example(): string {
      return mytest;
   }
   set example(val: string): string {
      this.mytest = val;
   }    
}

Upvotes: 1

amiramw
amiramw

Reputation: 506

I believe there is a problem with this line:

this.router.get('/get-test', this.getTest);

this.getTest is an unbound function reference. It has no context.

Try replacing it with:

this.router.get('/get-test', () => this.getTest);

Upvotes: 0

Related Questions