【问题标题】:TypeError: Cannot read property 'Tasks' of undefinedTypeError:无法读取未定义的属性“任务”
【发布时间】:2020-09-16 18:08:08
【问题描述】:

我是一个新手 Nodejs 编码器,并试图了解如何将 Sequelize ORM 与 Sqlite 一起使用。我创建了我的数据库并定义了所需的配置、路由、模型等。但是,当我在这个帖子 URL http://127.0.0.1:3000/tasks 上测试来自 Postman 的 API 时,我得到了错误。

  var Tasks = app.db.models.Tasks;
                            ^

TypeError: Cannot read property 'Tasks' of undefined
    at Function.module.exports (C:\Users\Utku\Desktop\msi-nb\Git Clones\nodejs_projects\nodejs-sqlit3-sequelize\src\routes\/tasks.js:2:31)
    at Consign.into (C:\Users\Utku\Desktop\msi-nb\Git Clones\nodejs_projects\nodejs-sqlit3-sequelize\node_modules\consign\lib\consign.js:240:17)
    at Object.<anonymous> (C:\Users\Utku\Desktop\msi-nb\Git Clones\nodejs_projects\nodejs-sqlit3-sequelize\src\/index.js:17:4)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)
    at Module._compile (C:\Users\Utku\Desktop\msi-nb\Git Clones\nodejs_projects\nodejs-sqlit3-sequelize\node_modules\pirates\lib\index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
    at Object.newLoader [as .js] (C:\Users\Utku\Desktop\msi-nb\Git Clones\nodejs_projects\nodejs-sqlit3-sequelize\node_modules\pirates\lib\index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! nodejs-sqlit3-sequelize@1.0.0 babel-node: `babel-node src/index.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the nodejs-sqlit3-sequelize@1.0.0 babel-node script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

我已经在网上查了解决方案。我没有使用sequelize.import,而是稍微更改了这些行并使用了require(),因为import 已被弃用。检查了我需要的库和文件。我错过了什么?这是代码。

index.js

import express from "express";
import consign from "consign";

const app = express();

consign({
  cwd: __dirname,
})
  .include('libs/config.js')
  .then('db.js')
  .then("libs/middlewares.js")
  .then('routes')
  .then("libs/boot.js")
  .into(app);

config.js

module.exports = {
  database: "task",
  username: "",
  password: "",
  params: {
    dialect: "sqlite",
    storage: "task-db.sqlite",
    define: {
      underscored: true,
    },
    operatorsAliases: false,
  },
};

db.js

import Sequelize from "sequelize";
import path from "path";
import fs from "fs";
const sqlite = require("sqlite3");

// let db = null;
let db = new sqlite.Database("task-db.sqlite");

module.exports = (app) => {
  if (!db) {
    const config = app.libs.config;

    const sequelize = new Sequelize(
      config.database,
      config.username,
      config.password,
      config.params
    );

    db = {
      sequelize,
      Sequelize,
      // app.db.models.Tasks
      // app.db.models.Users
      models: {},
    };

    // let modules = [require("./models/users"), require("./models/tasks")];

    const dir = path.join(__dirname, "models");
    fs.readdirSync(dir).forEach((filename) => {
      const modelDir = path.join(dir, filename);
      const model = require(modelDir);
      // const model = sequelize.import(modelDir);
      db.models[model.name] = model;
    });

    // // Initialize models
    // modules.forEach((module) => {
    //   const model = module(db.sequelize, db.Sequelize, config);
    //   db.models[model.name] = model;
    // });

    Object.keys(db.models).forEach((key) => {
      if (db.models[key].hasOwnProperty("associate")) {
        db.models[key].associate(db.models);
      }
    });
  }

  return db;
};

middleware.js

import express from 'express';

module.exports = app => {
  // Settings
  app.set('port', process.env.PORT || 3000);
  app.set('json spaces', 4);

  // Middlewares
  app.use(express.json());
  app.use((req, res, next) => {
    // Delete req.body.id;
    next();
  });

};

tasks.js

module.exports = (app) => {
  const Tasks = app.db.models.Tasks;

  app
    .route("/tasks")
    .get((req, res) => {
      Tasks.findAll({})
        .then((result) => res.json(result))
        .catch((error) => {
          res.status(412).json({ msg: error.message });
        });
    })
    .post((req, res) => {
      console.log(req.body);
      // To test post request
      // res.json({ status: "received" });

      Tasks.create(req.body)
        .then((result) => res.json(result))
        .catch((error) => {
          res.status(412).json({ msg: error.message });
        });
    });
};

boot.js

module.exports = app => {
  app.db.sequelize.sync(() => {
    app.listen(app.get('port'), () => {
      console.log('Server on port', app.get('port'));
    });
  });
};

tasks.js(模型)

module.exports = (sequelize, DataType) => {
  const Tasks = sequelize.define("Tasks", {
    id: {
      type: DataType.INTEGER,
      primaryKey: true,
      autoIncrement: true,
    },
    title: {
      type: DataType.STRING,
      allowNull: false,
      validate: {
        notEmpty: true,
      },
    },
    done: {
      type: DataType.BOOLEAN,
      allowNull: false,
      defaultValue: false,
    },
  });

  Tasks.associate = (models) => {
    Tasks.belongsTo(models.Users);
  };

  return Tasks;
};

文件夹结构

【问题讨论】:

    标签: node.js sqlite sequelize.js


    【解决方案1】:

    如果tasks.js 中的模型名称为task,则应使用app.db.models.task。如果你的模型名称是Task,你应该使用app.db.models.Task

    【讨论】:

    • 我已经编辑了我的问题并添加了模型部分。实际上,我做的是“返回任务”;因为,如您所见,我创建了一个“任务”对象。将名称“Tasks”更改为小写并不会改变结果。 TypeError:无法读取未定义的属性“任务”
    • 将模型名称更改为'Task' sequelize 自动在模型名称末尾添加's'
    • 在定义函数内部更改为 sequelize.define("Task", {...}) 后,我仍然遇到同样的错误。
    • db.js中'db.models'的值是多少?
    • 当我打印该值时,它显示“未定义”。我不太确定, const model = require(modelDir);是正确的选择。我评论了它,尝试了 sequelize.import,但没有一个能解决问题。
    【解决方案2】:

    终于找到了解决办法

    我删除了这一行:

    let db = new sqlite.Database("task-db.sqlite");
    

    改用这个:

    let db = null;
    

    我把下面的所有代码都注释掉了:

    // Initialize models
    const dir = path.join(__dirname, "models");
    fs.readdirSync(dir).forEach((filename) => {
      const modelDir = path.join(dir, filename);
      const model = require(modelDir);
      // const model = sequelize.import(modelDir);
      db.models[model.name] = model;
    });
    

    相反,我使用了以下几行:

    let modules = [require("./models/users"), require("./models/tasks")];
    
    // Initialize models
    modules.forEach((module) => {
       const model = module(db.sequelize, db.Sequelize, config);
       console.log(model.name);
       db.models[model.name] = model;
    });
    

    最后我还修改了boot.js文件,添加了force: true.then()

    module.exports = app => {
      app.db.sequelize.sync({force: true}).then(() => {
        app.listen(app.get('port'), () => {
          console.log('Server on port', app.get('port'));
        });
      });
    };
    

    我删除了之前创建的 db 文件并从 cmd 运行命令。它成功了,我成功发送了发布请求。

    【讨论】:

      猜你喜欢
      • 2021-04-28
      • 2018-10-23
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-24
      相关资源
      最近更新 更多