Michael
Michael

Reputation: 43

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;
    }

}

Upvotes: 0

Views: 1576

Answers (2)

nahanikito
nahanikito

Reputation: 46

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);

Upvotes: 1

Corvus Crypto
Corvus Crypto

Reputation: 2291

At a quick glance it looks like a scope issue since at the time of invokation this refers to the scope of Http.createServer(). A quick fix would be to bind to the actual object scope imo.

Upvotes: 0

Related Questions