繁体   English   中英

TypeError - 无法读取未定义的属性(读取“名称”)

[英]TypeError - Cannot read properties of undefined (reading 'name')

基本上我在尝试在 Deno 上使用UseCase class 时遇到了这个错误。

[uncaught application error]: TypeError - Cannot read properties of undefined (reading 'getAppInfosUseCase')

request: { url: "http://127.0.0.1:3030/", method: "GET", hasBody: false }
response: { status: 200, type: undefined, hasBody: false, writable: true }

    at handle (file:///C:/Users/joaop/Documents/dev/web/back-end/deno/shynotes-api%20(MVC)/src/useCases/GetAppInfos/GetAppInfosController.ts:11:39)
    at dispatch (https://deno.land/x/oak@v10.6.0/middleware.ts:41:13)
    at https://deno.land/x/oak@v10.6.0/router.ts:1148:20
    at dispatch (https://deno.land/x/oak@v10.6.0/middleware.ts:41:13)
    at composedMiddleware (https://deno.land/x/oak@v10.6.0/middleware.ts:44:12)
    at dispatch (https://deno.land/x/oak@v10.6.0/router.ts:1154:28)
    at dispatch (https://deno.land/x/oak@v10.6.0/middleware.ts:41:13)
    at composedMiddleware (https://deno.land/x/oak@v10.6.0/middleware.ts:44:12)
    at Application.#handleRequest (https://deno.land/x/oak@v10.6.0/application.ts:389:34)
    at Application.listen (https://deno.land/x/oak@v10.6.0/application.ts:559:28)

应用结构

项目结构

src/

应用程序.ts

import { Application } from 'https://deno.land/x/oak@v10.6.0/mod.ts';
import { router } from './routes.ts';
import 'https://deno.land/x/dotenv@v3.2.0/load.ts';

const app = new Application();

app.use(router.routes());
app.use(router.allowedMethods());

export { app };

路线.ts

import { Router } from 'https://deno.land/x/oak@v10.6.0/router.ts';
import { getAppInfosController } from './useCases/GetAppInfos/index.ts';

const router = new Router();

router.get('/', getAppInfosController.handle);

export { router };

服务器.ts

import { app } from './app.ts';

await app.listen({
    port: 3030,
});

src/useCases/

GetAppInfosController.ts

import { Context } from 'https://deno.land/x/oak@v10.6.0/context.ts';
import { GetAppInfosUseCase } from './GetAppInfosUseCase.ts';

export class GetAppInfosController {
    constructor(
        private getAppInfosUseCase: GetAppInfosUseCase,
    ) {}

    handle(context: Context) {
        context.response.status = 200;
        return context.response.body = this.getAppInfosUseCase.execute();
    }
}

GetAppInfosUseCase.ts

export class GetAppInfosUseCase {
    execute() {
        return {
            author: 'Jphn',
            github: 'github.com/Jphn',
        };
    }
}

索引.ts

import { GetAppInfosUseCase } from './GetAppInfosUseCase.ts';
import { GetAppInfosController } from './GetAppInfosController.ts';

const getAppInfosUseCase = new GetAppInfosUseCase();

const getAppInfosController = new GetAppInfosController(getAppInfosUseCase);

export { getAppInfosController, getAppInfosUseCase };

服务器.ts

import { Router } from 'https://deno.land/x/oak@v10.6.0/router.ts';
import { getAppInfosController } from './useCases/GetAppInfos/index.ts';

const router = new Router();

// router.get('/', getAppInfosController.handle);
router.get('/', (context) => {
  getAppInfosController.handle(context);
});

export { router };

这个问题似乎您需要帮助调试。 我将您问题中的数据复制到我的文件系统目录中的文件中以进行复制。 让我们从一些基础知识开始:

我正在使用的 Deno 版本:

% deno --version
deno 1.24.0 (release, x86_64-apple-darwin)
v8 10.4.132.20
typescript 4.7.4

类型检查您的代码:

% deno check src/server.ts 
Download https://deno.land/x/dotenv@v3.2.0/load.ts
Download https://deno.land/x/dotenv@v3.2.0/mod.ts
Download https://deno.land/x/dotenv@v3.2.0/util.ts
error: Module not found "file:///Users/deno/so-73142682/src/useCases/GetAppInfos/index.ts".
    at file:///Users/deno/so-73142682/src/routes.ts:2:39

揭示的第一个问题是./src/routes.ts中有一个无效的模块说明符:

import { Router } from 'https://deno.land/x/oak@v10.6.0/router.ts';
import { getAppInfosController } from './useCases/GetAppInfos/index.ts'; /*
                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to load a local module: "file:///Users/deno/so-73142682/src/useCases/GetAppInfos/index.ts".
  Please check the file path. deno(no-local) */

const router = new Router();

router.get('/', getAppInfosController.handle);

export { router };

说明符只需更改为"./useCases/index.ts" 进行更改后,让我们再次进行类型检查:

% deno check src/server.ts
Check file:///Users/deno/so-73142682/src/server.ts

现在类型检查通过了:太好了。 让我们尝试运行该模块:

% deno run --allow-read=".env,.env.defaults" --allow-net="0.0.0.0:3030" src/server.ts

该过程不会终止,所以发生了一些事情。 让我们尝试向主机发出 GET 请求。 在单独的终端 shell 中:

% deno eval --print "(await fetch('http://localhost:3030')).status"
500

请求的状态是500 让我们切换回运行应用程序的 shell 并检查是否有任何 output。 有:

[uncaught application error]: TypeError - Cannot read properties of undefined (reading 'getAppInfosUseCase')

request: { url: "http://localhost:3030/", method: "GET", hasBody: false }
response: { status: 200, type: undefined, hasBody: false, writable: true }

    at handle (file:///Users/deno/so-73142682/src/useCases/GetAppInfosController.ts:11:45)
    at dispatch (https://deno.land/x/oak@v10.6.0/middleware.ts:41:13)
    at https://deno.land/x/oak@v10.6.0/router.ts:1148:20
    at dispatch (https://deno.land/x/oak@v10.6.0/middleware.ts:41:13)
    at composedMiddleware (https://deno.land/x/oak@v10.6.0/middleware.ts:44:12)
    at dispatch (https://deno.land/x/oak@v10.6.0/router.ts:1154:28)
    at dispatch (https://deno.land/x/oak@v10.6.0/middleware.ts:41:13)
    at composedMiddleware (https://deno.land/x/oak@v10.6.0/middleware.ts:44:12)
    at Application.#handleRequest (https://deno.land/x/oak@v10.6.0/application.ts:389:34)
    at Application.listen (https://deno.land/x/oak@v10.6.0/application.ts:559:28)

查看堆栈跟踪的开头显示错误源自此位置:

at handle (file:///Users/deno/so-73142682/src/useCases/GetAppInfosController.ts:11:45)

11:45表示第 11 行第 45 列。让我们检查源模块 ./src/useCases/GetAppInfosController.ts 中的./src/useCases/GetAppInfosController.ts

import { Context } from 'https://deno.land/x/oak@v10.6.0/context.ts';
import { GetAppInfosUseCase } from './GetAppInfosUseCase.ts';

export class GetAppInfosController {
    constructor(
        private getAppInfosUseCase: GetAppInfosUseCase,
    ) {}

    handle(context: Context) {
        context.response.status = 200;
        return context.response.body = this.getAppInfosUseCase.execute(); /*
                                            ~~~~~~~~~~~~~~~~~~
                                      Here's where the error occurred.
                                  `this` was `undefined` at the call site */
    }
}

堆栈并没有使这一点变得明显,但实际问题是您在./src/routes.ts中使用handle方法的位置:

import { Router } from 'https://deno.land/x/oak@v10.6.0/router.ts';
import { getAppInfosController } from './useCases/index.ts';

const router = new Router();

router.get('/', getAppInfosController.handle); /*
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                This is an unbound method call */

export { router };

方法绑定已经在本站的其他问题中进行了广泛的讨论,所以我不会在这里重复细节。 You just need to bind the class instance object to the method so that when it's invoked as a function, the this value refers to the class instance object:

router.get('/', getAppInfosController.handle.bind(getAppInfosController));
//                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

保存这些更改后,让我们在终端中使用ctrl + c停止应用程序并重新启动它:

^C

% deno run --allow-read=".env,.env.defaults" --allow-net="0.0.0.0:3030" src/server.ts

现在让我们在单独的终端 shell 中向主机发出另一个 GET 请求,但这次我们将打印正文为解析的 JSON(因为这是预期的响应格式):

% deno eval --print "await (await fetch('http://localhost:3030')).json()"
{ author: "Jphn", github: "github.com/Jphn" }

现在它看起来像预期的那样。 问题解决了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM