最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Express JS: Cannot read property 'lazyrouter' of undefined - Stack Overflow

programmeradmin1浏览0评论

I'm creating a layer of abstraction around Express JS and I've encountered a problem. Considering the following code (see bottom), when calling registerRoute and hitting the line:

expressFnc(route, (req: any, res: any, next: any) => dummy(req, res, next));

I am encountering the error:

Cannot read property 'lazyrouter' of undefined

In this context 'this', I assume, applies to ExpressJS (lib/application.js:479:10).

const express = require("express");

export class ExpressHttpHost implements IHttpHost {
  private host: any = express();
  private contentResolver?: ContentResolver;

  public configure(contentResolver: ContentResolver): void {
    this.contentResolver = contentResolver;
  }

  public registerRoute(
    route: string,
    verb: HttpVerb,
    handler: (request: HttpRequest) => HttpResponse,
  ): void {
    switch (verb) {
      case HttpVerb.Get:
        this.createDummyRequest(this.host.get, route, handler);
        break;
      case HttpVerb.Delete:
        this.createDummyRequest(this.host.delete, route, handler);
        break;
      case HttpVerb.Options:
        this.createDummyRequest(this.host.options, route, handler);
        break;
      case HttpVerb.Patch:
        this.createDummyRequest(this.host.patch, route, handler);
        break;
      case HttpVerb.Post:
        this.createDummyRequest(this.host.post, route, handler);
        break;
      case HttpVerb.Put:
        this.createDummyRequest(this.host.put, route, handler);
        break;
      case HttpVerb.All:
        this.createDummyRequest(this.host.get, route, handler);
        this.createDummyRequest(this.host.delete, route, handler);
        this.createDummyRequest(this.host.options, route, handler);
        this.createDummyRequest(this.host.patch, route, handler);
        this.createDummyRequest(this.host.post, route, handler);
        this.createDummyRequest(this.host.put, route, handler);
        break;
      default:
        throw new Error("Verb is not supported.");
    }
  }

  public start(options: IHttpHostOptions): void {
    this.host.listen(options.port ? options.port : 80);
  }

  private createHttpRequest(expressReq: any): HttpRequest {
    return new HttpRequest(
      expressReq.headers,
      expressReq.params,
      expressReq.body,
    );
  }

  private createDummyRequest(expressFnc: any, route: string, handler: (request: HttpRequest) => HttpResponse): void {
    const dummy = (expressReq: any, expressRes: any, next: any) => {
      const httpRequest = this.createHttpRequest(expressReq);

      const response = handler(httpRequest);
      const responseStatus = response.status();
      const responseMimeType = response.mimeType();
      const responseContent = response.content(this.contentResolver);

      expressRes.set("Content-Type", responseMimeType);
      expressRes.status(responseStatus);
      expressRes.send(responseContent);
      next();
    };
    expressFnc(route, (req: any, res: any, next: any) => dummy(req, res, next));
  }
}

I'm creating a layer of abstraction around Express JS and I've encountered a problem. Considering the following code (see bottom), when calling registerRoute and hitting the line:

expressFnc(route, (req: any, res: any, next: any) => dummy(req, res, next));

I am encountering the error:

Cannot read property 'lazyrouter' of undefined

In this context 'this', I assume, applies to ExpressJS (lib/application.js:479:10).

const express = require("express");

export class ExpressHttpHost implements IHttpHost {
  private host: any = express();
  private contentResolver?: ContentResolver;

  public configure(contentResolver: ContentResolver): void {
    this.contentResolver = contentResolver;
  }

  public registerRoute(
    route: string,
    verb: HttpVerb,
    handler: (request: HttpRequest) => HttpResponse,
  ): void {
    switch (verb) {
      case HttpVerb.Get:
        this.createDummyRequest(this.host.get, route, handler);
        break;
      case HttpVerb.Delete:
        this.createDummyRequest(this.host.delete, route, handler);
        break;
      case HttpVerb.Options:
        this.createDummyRequest(this.host.options, route, handler);
        break;
      case HttpVerb.Patch:
        this.createDummyRequest(this.host.patch, route, handler);
        break;
      case HttpVerb.Post:
        this.createDummyRequest(this.host.post, route, handler);
        break;
      case HttpVerb.Put:
        this.createDummyRequest(this.host.put, route, handler);
        break;
      case HttpVerb.All:
        this.createDummyRequest(this.host.get, route, handler);
        this.createDummyRequest(this.host.delete, route, handler);
        this.createDummyRequest(this.host.options, route, handler);
        this.createDummyRequest(this.host.patch, route, handler);
        this.createDummyRequest(this.host.post, route, handler);
        this.createDummyRequest(this.host.put, route, handler);
        break;
      default:
        throw new Error("Verb is not supported.");
    }
  }

  public start(options: IHttpHostOptions): void {
    this.host.listen(options.port ? options.port : 80);
  }

  private createHttpRequest(expressReq: any): HttpRequest {
    return new HttpRequest(
      expressReq.headers,
      expressReq.params,
      expressReq.body,
    );
  }

  private createDummyRequest(expressFnc: any, route: string, handler: (request: HttpRequest) => HttpResponse): void {
    const dummy = (expressReq: any, expressRes: any, next: any) => {
      const httpRequest = this.createHttpRequest(expressReq);

      const response = handler(httpRequest);
      const responseStatus = response.status();
      const responseMimeType = response.mimeType();
      const responseContent = response.content(this.contentResolver);

      expressRes.set("Content-Type", responseMimeType);
      expressRes.status(responseStatus);
      expressRes.send(responseContent);
      next();
    };
    expressFnc(route, (req: any, res: any, next: any) => dummy(req, res, next));
  }
}
Share Improve this question edited Jun 14, 2019 at 13:18 Aluan Haddad 31.9k10 gold badges83 silver badges95 bronze badges asked Jun 6, 2019 at 8:46 jProg2015jProg2015 1,12811 silver badges44 bronze badges 2
  • might you be encountering a similar issue to the one outlined in this issue post?: github./expressjs/express/issues/3855 – dusthaines Commented Jun 14, 2019 at 13:20
  • 1 FWIW i also get this error if I mistype the name of a function and pass an empty value instead to the router, e.g. app.get('/api/route/:param', undefined) – prototype Commented Jul 12, 2021 at 2:08
Add a ment  | 

2 Answers 2

Reset to default 6 +50

This might happen because express functions when passed as arguments loose reference to the host object. Try manually binding them back. See the bindings below in the switch:

const express = require("express");

export class ExpressHttpHost implements IHttpHost {
  private host: any = express();
  private contentResolver?: ContentResolver;

  public configure(contentResolver: ContentResolver): void {
    this.contentResolver = contentResolver;
  }

  public registerRoute(
    route: string,
    verb: HttpVerb,
    handler: (request: HttpRequest) => HttpResponse,
  ): void {
    switch (verb) {
      case HttpVerb.Get:
        this.createDummyRequest(this.host.get.bind(this.host), route, handler);
        break;
      case HttpVerb.Delete:
        this.createDummyRequest(this.host.delete.bind(this.host), route, handler);
        break;
      case HttpVerb.Options:
        this.createDummyRequest(this.host.options.bind(this.host), route, handler);
        break;
      case HttpVerb.Patch:
        this.createDummyRequest(this.host.patch.bind(this.host), route, handler);
        break;
      case HttpVerb.Post:
        this.createDummyRequest(this.host.post.bind(this.host), route, handler);
        break;
      case HttpVerb.Put:
        this.createDummyRequest(this.host.put.bind(this.host), route, handler);
        break;
      case HttpVerb.All:
        this.createDummyRequest(this.host.get.bind(this.host), route, handler);
        this.createDummyRequest(this.host.delete.bind(this.host), route, handler);
        this.createDummyRequest(this.host.options.bind(this.host), route, handler);
        this.createDummyRequest(this.host.patch.bind(this.host), route, handler);
        this.createDummyRequest(this.host.post.bind(this.host), route, handler);
        this.createDummyRequest(this.host.put.bind(this.host), route, handler);
        break;
      default:
        throw new Error("Verb is not supported.");
    }
  }

  public start(options: IHttpHostOptions): void {
    this.host.listen(options.port ? options.port : 80);
  }

  private createHttpRequest(expressReq: any): HttpRequest {
    return new HttpRequest(
      expressReq.headers,
      expressReq.params,
      expressReq.body,
    );
  }

  private createDummyRequest(expressFnc: any, route: string, handler: (request: HttpRequest) => HttpResponse): void {
    const dummy = (expressReq: any, expressRes: any, next: any) => {
      const httpRequest = this.createHttpRequest(expressReq);

      const response = handler(httpRequest);
      const responseStatus = response.status();
      const responseMimeType = response.mimeType();
      const responseContent = response.content(this.contentResolver);

      expressRes.set("Content-Type", responseMimeType);
      expressRes.status(responseStatus);
      expressRes.send(responseContent);
      next();
    };
    expressFnc(route, (req: any, res: any, next: any) => dummy(req, res, next));
  }
}

This problem happened to me and took me hours and extra support to resolve. My advice is to read the pilation error well, because it should tell you where in your codebase the error is caused.

In my case it was caused by

server.post(`/url/path/to/page`, myMiddleware(), MyClass.myNonExistentFunction);

The reference to a non-existent function had crept into my codebase when during a plicated merge.

Part of the problem with this pilation error is that it doesn't name the undefined callback - in this case 'MyClass.myNonExistentFunction'.

发布评论

评论列表(0)

  1. 暂无评论