无法读取node.js中未定义的属性'then'?

时间:2019-12-27 06:40:19

标签: node.js mongodb express apollo-server

在models / index.js文件中,我正在尝试编写数据库连接

const connectDb = () => {
  if (process.env.TEST_DATABASE_URL) {
    return mongoose.connect(
      process.env.TEST_DATABASE_URL,
      { useNewUrlParser: true },
    );
  }

  if (process.env.DATABASE_URL) {
    return mongoose.connect(
      process.env.DATABASE_URL,
      { useNewUrlParser: true },
    );
  }
};

在主index.js文件中,我试图像下面这样调用connectDb()函数:-

connectDb().then(async () => {
  if (isTest || isProduction) {
    // reset database
    await Promise.all([
      models.User.deleteMany({}),
      models.Message.deleteMany({}),
    ]);

    createUsersWithMessages(new Date());
  }

  httpServer.listen({ port }, () => {
    console.log(`Apollo Server on http://localhost:${port}/graphql`);
  });
});

我收到以下错误:-

TypeError: Cannot read property 'then' of undefined
    at Object.<anonymous> (D:\Gaurav's-Stuff\fullstack-apollo-express-mongodb-boilerplate\src/index.js:95:1)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Module._compile (D:\Gaurav's-Stuff\fullstack-apollo-express-mongodb-boilerplate\node_modules\pirates\lib\index.js:83:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Object.newLoader [as .js] (D:\Gaurav's-Stuff\fullstack-apollo-express-mongodb-boilerplate\node_modules\pirates\lib\index.js:88:7)        
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at Object.<anonymous> (D:\Gaurav's-Stuff\fullstack-apollo-express-mongodb-boilerplate\node_modules\@babel\node\lib\_babel-node.js:224:23)   
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)```

2 个答案:

答案 0 :(得分:1)

如果遇到此错误:

TypeError: Cannot read property 'then' of undefined

从以下代码行:

connectDb().then(async () => {

然后,这意味着connectDb()返回undefined而不是返回承诺。

查看该代码:

const connectDb = () => {
  if (process.env.TEST_DATABASE_URL) {
    return mongoose.connect(
      process.env.TEST_DATABASE_URL,
      { useNewUrlParser: true },
    );
  }

  if (process.env.DATABASE_URL) {
    return mongoose.connect(
      process.env.DATABASE_URL,
      { useNewUrlParser: true },
    );
  }
};

我们知道,在您所说的猫鼬版本中,mongoose.connect()已经返回了保证,因此connectDb()不能返回保证的唯一方法是,如果两个if都声明如果process.env.TEST_DATABASE_URLprocess.env.DATABASE_URL都没有值,或者mongoose.connect()实际上没有返回诺言(您以某种方式安装了旧版本的猫鼬),则计算为false。

验证环境变量的一种简单方法是仅添加几个日志语句:

const connectDb = () => {
  if (process.env.TEST_DATABASE_URL) {
    console.log("Found TEST_DATABASE_URL");
    return mongoose.connect(
      process.env.TEST_DATABASE_URL,
      { useNewUrlParser: true },
    );
  }

  if (process.env.DATABASE_URL) {
    console.log("Found DATABASE_URL");
    return mongoose.connect(
      process.env.DATABASE_URL,
      { useNewUrlParser: true },
    );
  }

  console.log("Never supposed to get here")
  throw new Error("Need either TEST_DATABASE_URL OR DATABASE_URL set in the environment");
};

仅供参考,从数据库连接开始,在第二个代码块中,您的代码中有很多地方没有进行正确的错误检测或处理。

答案 1 :(得分:0)

这应该有效

const connectDb = async () => {
  let x = null;
  if (process.env.TEST_DATABASE_URL) {
    x = await mongoose.connect(
      process.env.TEST_DATABASE_URL,
      { useNewUrlParser: true },
    );
  }

  if (process.env.DATABASE_URL) {
    x = await mongoose.connect(
      process.env.DATABASE_URL,
      { useNewUrlParser: true },
    );
  }
  if(x){ return Promise.resolve(db) } else { return Promise.reject("reject"); }

};