【问题标题】:fastify-mongodb : "mongo" is undefined when accessedfastify-mongodb : "mongo" 在访问时未定义
【发布时间】:2019-11-12 17:05:34
【问题描述】:

我正在尝试使用 Fastify 和 fastify-monogdb。 目前我有以下...

在我的 /src/index.js

const routes = require("./routes");
const fastify = require("fastify")({
  logger: true
});

routes.forEach((route, index) => {
  fastify.route(route);
});

fastify.register(require("fastify-mongodb"), {
  url: "mongodb://localhost:27017/parkedcars"
});

const startFastify = async () => {
  try {
    await fastify.listen(3333);
    fastify.log.info(`server listening on ${fastify.server.address().port}`);
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};

startFastify();

在我的 /routes/index.js 我有一条路线...

const carController = require("../controllers/carController");

  {
    method: "POST",
    url: "/api/create/parkedcar",
    handler: carController.createParkedCar
  }

最后在我的 /controllers/carController...

const fastify = require("fastify")();

  exports.createParkedCar = async (req, reply) => {
  try {
    let car = { ...req.body };
    const db = fastify.mongo.db
    *// will do insert here*
    return car;
  } catch (err) {
    throw boom.boomify(err);
  }
};

当我尝试调用时:
const db = fastify.mongo.db

我收到一条错误消息...
“无法读取未定义的属性 'db'”

我在这里做错了什么?
mongo 在这一点上如何未定义?
“fastify.register”不是让我可以访问它吗?

【问题讨论】:

  • 你不需要在 carController 中要求 fastify。在控制器中使用 this.mongo 参见这个例子github.com/fastify/fastify-mongodb#usage 如果你需要在控制器中使用 fastify 的方式,你正在创建新的 fastify 实例。
  • 试过了。还是同样的错误。在“/src/index.js”中使用“this”。在“/src/index.js”中也可以使用“fastify.mongo.db”,当从不同的 JS 文件访问时,“this”如何引用 fastify?
  • "this" 指的是 fastify,因为虽然我没有检查过,但处理程序是用 fastify 上下文调用的。 ...handler.call(fastify, request, reply) 你得到相同错误的唯一原因是我能想到的添加 fastify.register 的顺序很重要(就像在 Express.js 中一样)所以尝试将 routes.forEach... 移动到代码 fastify.register(require("fastify-mongodb")...
  • 我想我刚刚发现了这个问题。通过像我所做的那样将路由放在一个单独的文件中,您无法访问 Fastify 实例。看到这个:github.com/fastify/fastify/issues/392
  • 顺便说一下,他们在这里提出了一些处理方法:github.com/fastify/fastify-mongodb/issues/9

标签: node.js mongodb fastify


【解决方案1】:

您需要在每个应用程序中执行一次require("fastify")() only,因为它是工厂而不是单例,因此每次运行要求时,您都在创建一个全新的 HTTP 服务器!

神奇的是以正确的方式使用.register 和/或在处理程序中使用function 而不是箭头函数。

对于您的用例,您可以更改 carController:

  exports.createParkedCar = function handler (req, reply) {
    let car = { ...req.body };
    const db = this.mongo.db
    *// will do insert here*
    db.insert(...)
      .then(() => reply.send(car))
      .catch((err) => reply.send(boom.boomify(err)))
  }

因为所有的函数处理程序,在 fastify 中,都绑定到了 fastify 服务器实例上(比如 aFunction.bind(fastify))。箭头函数无法绑定。

另一种选择是使用寄存器:

// /routes/index.js

module.exports = (fastify, opts, next) => {

  fastify.route({
    method: "POST",
    url: "/api/create/parkedcar",
    handler: async (req, reply) => {
      try {
        let car = { ...req.body };
        const db = fastify.mongo.db
        *// will do insert here*
        return car;
      } catch (err) {
        throw boom.boomify(err);
      }
  });

  next() // dont forget it
}

欲了解更多信息,请查看the docs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    相关资源
    最近更新 更多