簡體   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