Michael Michael - 22 days ago 7
Javascript Question

TypeError: this.name is not a function

In the below code I always get an error "TypeError: this.verifyUrl is not a function at Server.ImageServer.handleRequest" even though the function is defined above.

Any hint welcome.

The same applies if i write the sample in pure JavaScript.

"use strict";

import Http = require('http');
import Url = require('url');

export class ImageServer {

port: number;
server: Http.Server;

constructor(port: number) {
this.port = port || 1337;
}

run() {
this.server = Http.createServer(this.handleRequest);
this.server.listen(this.port);
}

verifyUrl(urlitems: Url.Url) {
return true;
}

handleRequest(req: Http.IncomingMessage, res: Http.ServerResponse) {
console.log('request: ', req.url);
var urlitems = Url.parse(req.url, true);
var pathitems = urlitems.path.split('/').slice(1);

console.log('url: ', urlitems);
console.log('path: ', pathitems);

if (!this.verifyUrl(urlitems)) {
this.sendNotFound(res);
return;
}

res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
}

sendNotFound(res: Http.ServerResponse) {
res.statusCode = 404;
res.end();
return undefined;
}

}

Answer

Try this:

"use strict";

import Http = require('http');
import Url = require('url');

export class ImageServer {

    port: number;
    server: Http.Server;

    constructor(port: number) {
        this.port = port || 1337;
    }

    run() {
        this.server = Http.createServer(this.handleRequest);
        this.server.listen(this.port);
    }

    verifyUrl(urlitems: Url.Url) {
        return true;
    }

    handleRequest = (req: Http.IncomingMessage, res: Http.ServerResponse) => {
        console.log('request: ', req.url);
        var urlitems = Url.parse(req.url, true);
        var pathitems = urlitems.path.split('/').slice(1);

        console.log('url: ', urlitems);
        console.log('path: ', pathitems);

        if (!this.verifyUrl(urlitems)) {
            this.sendNotFound(res);
            return;
        }

        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('Hello World\n');
    }

    sendNotFound(res: Http.ServerResponse) {
        res.statusCode = 404;
        res.end();
        return undefined;
    }

}

I suppose you call handleRequest as a callback from a module (probably expressjs?), so this is not binded to the class scope but to the module's scope. Using arrow functions, this will be automatically assigned to the class scope and so you can access to your class functions/properties

Here's your problem explained with examples

class Hi {
   hello: string = "Hello world!";

   haha(req: Http.IncomingMessage, res: Http.ServerResponse) {
      console.log(this.hello) // print undefined or error
   }
}

var hi = new Hi();

app.get("/foo", hi.haha);

With this code, you can't access to the class properties because this is assigned to express.

You can fix it as said above with arrow functions. Here's a working example:

class Hi {
   hello: string = "Hello world!";

   haha = (req: Http.IncomingMessage, res: Http.ServerResponse) => {
      console.log(this.hello) // print Hello world!
   }
}

var hi = new Hi();

app.get("/foo", hi.haha);
Comments