Использование сервиса в Express Router

Я довольно новичок в NodeJS, но я хотел бы узнать что-то новое. Я пришел из.NET, привнесения зависимостей, инверсии управления, микросервисного блестящего мира, поэтому я пытаюсь написать какой-нибудь сервис на TypeScript, основываясь на моем предыдущем опыте. Я использую экспресс и экспресс-маршрутизатор для создания API. У меня есть несколько методов в маршрутизаторе, который обрабатывает вызовы API, и я хочу использовать какой-то объект службы для извлечения и обработки данных. Я внедряю сервис в маршрутизатор, используя конструктор, но если я хочу использовать свой сервис, он выдает ошибку:

TypeError: Невозможно прочитать свойство layoutService из неопределенного

Я понял, что методы были вызваны без контекста, поэтому я добавил .bind(this) к каждому методу регистрации, и он работает, но я не знаю, является ли это лучшим способом, как это сделать.

У кого-нибудь есть идея получше?

упрощенный server.ts

import express, { Router } from "express";

// inversion of controll
import container from "./ioc";
import { TYPE } from "./constants";

import IMyService from "./abstract/IMyService";

// import routers
import MyRouter from "./api/MyRouter";

app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const router: Router = express.Router();
const myRouter: MyRouter = new MyRouter(container.get<IMyService>(TYPE.IMyService));

app.use("/", router);
app.use("/api/v1/layouts", layoutRouter.router);

MyRouter.ts

import IMyService from "./abstract/IMyService";
import { Router, Request, Response } from "express";
import { inject } from "inversify";
import { TYPE } from "../constants";

export default class MyRouter {
    public readonly router: Router;
    private readonly myService: IMyService;

    constructor(
        @inject(TYPE.IMyService) myService: IMyService
    ) {
        this.myService = myService;
        this.router = Router();
        this.routes();
    }

    public GetAll(req: Request, res: Response): void {
        this.myService.getAll()
            .then(data => {
                const status: number = res.statusCode;

                res.json({ status, data });
            })
            .catch(err => {
                const status: number = res.statusCode;

                res.json({ status, err });
            });
    }   

    public GetOne(req: Request, res: Response): void {
        const id: string = req.params.id;

        this.myService.getOne(new ObjectID(id))
            .then(data => {
                const status: number = res.statusCode;

                res.json({ status, data });
            })
            .catch(err => {
                const status: number = res.statusCode;

                res.json({ status, err });
            });
    }

    routes(): void {
        this.router
            .get("/", this.GetAll)
            .get("/:id", this.GetOne);
    }
}

1 ответ

Решение

Если вы определите свою функцию с помощью синтаксиса стрелки (ES6), она автоматически "свяжет" контекст с ней, и вам не нужно будет bind их. Но это будет зависеть от вашего варианта использования (вам может понадобиться связать другой контекст)

Другие вопросы по тегам