【问题标题】:TypeError: Cannot read property 'name' of undefined in Node js with ExpressTypeError:无法使用 Express 读取 Node js 中未定义的属性“名称”
【发布时间】:2020-01-22 17:14:12
【问题描述】:

我正在使用本地 .json 文件作为我的小型 Web 应用程序的数据库。它可以正常工作,我可以从中检索数据,但是当我查看控制台时,我看到错误 TypeError: Cannot read property 'name' of undefined... 每次出现两次。错误不一致,我无法正确复制它,我不明白是什么原因造成的。

JSON

{
  "Faction1": {
    "name": "Lorem Ipsum",
    "id": "lorem-ipsum",
    "content": {
      "colors": {
        "col1": "red",
        "col2": "white",
        "col3": "grey"
      }
    }
  }
}

App.js

    //jshint esversion:6
    const express = require("express");
    const bodyParser = require('body-parser');
    const favicon = require('serve-favicon');

    const app = express();

    app.set('view engine', 'ejs');

    app.use(favicon(__dirname + '/public/favicon.ico'));

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

    app.use(express.static(__dirname + '/public'));

    app.use('/scripts', express.static( __dirname + '/node_modules/'));


    const factionsDb = require(__dirname + '/views/data/factions.json');

    JSON.stringify(factionsDb);

    // -------------------------------------------------------------------------- //

    app.get('/', (req, res) => {
      res.render('pages/index', {
      pageTitle: "App Name"
      });
    });


    app.get('/factions', (req, res) => {
      res.render('pages/product-list', {
        parentPage: "'/'",
        pageTitle: "Factions",
        section: "factions",
        productsList: factionsDb
      });
    });

    app.get('/factions/:productId', (req, res) => {
      let requestedProductId = req.params.productId;

      let selectedProduct = Object.values(factionsDb).find(product => Object.values(product).includes(requestedProductId));

      res.render('pages/product-details', {
        parentPage: "'../factions'",
        pageTitle: selectedProduct.name,
        section: "factions",
        product: selectedProduct
      });
    })

    app.listen(3000, function(){
      console.log("Server started on port 3000");
    });

    // -------------------------------------------------------------------------- //

    app.use(function (req, res) {
        res.status(404).render('pages/404', {parentPage: "'/'", pageTitle: ""},
      );
    });

【问题讨论】:

    标签: node.js json express


    【解决方案1】:

    如果您选择不存在的产品,那么selectedProduct 将是undefined

    let selectedProduct = Object.values(factionsDb).find(product => Object.values(product).includes(requestedProductId));
    

    然后您尝试设置以下pageTitle: selectedProduct.name,,它进入selectedProduct 变量并尝试在其中找到对象name。由于 selectedProduct 未定义,因此会引发您提到的错误。

    你应该可以通过一些废话:productId调用URL来模拟它,即/factions/nonexistingfaction

    【讨论】:

    • 对象 'name' 总是在 json 中指定,并且选择的产品总是被定义,我不明白为什么它没有找到它,导航仍然继续。
    【解决方案2】:

    需要通过查找功能检查是否有匹配的项目。

    `let selectedProduct = Object.values(factionsDb).find(product => Object.values(product).includes(requestedProductId));

    如果没有匹配的项目,它会返回 undefined 所以尝试检查 selectedProduct。

    下面我更新了pageTitle部分。

      res.render('pages/product-details', {
        parentPage: "'../factions'",
        pageTitle: (selectedProduct && selectedProduct !== undefined)?  selectedProduct.name : '',
        section: "factions",
        product: selectedProduct
      });
    

    同步:

    var fs = require('fs');
    var obj = JSON.parse(fs.readFileSync('file', 'utf8'));
    

    异步:

    var fs = require('fs');
    var obj;
    fs.readFile('file', 'utf8', function (err, data) {
      if (err) throw err;
      obj = JSON.parse(data);
    });
    

    【讨论】:

    • 这很奇怪,因为导航总是按现有产品进行,数据库是静态的,而且我不会搜索不存在的产品。我插入了您的修改,现在它在控制台中告诉我“无法读取未定义的属性 'id'”(在产品详细信息模板中使用)
    • 尝试以同样的方式检查 id 属性的使用情况。它不完全匹配,因此您确实遇到了该错误所以请尝试再次检查匹配的产品代码库。
    • 如果我将console.log(selectedProduct.name); 放在res.render 之前,它总是显示正确的名称属性,但之后也会显示错误,所以我不知道为什么它找不到它。我发现这个错误大多是第一次出现,在短暂的不活动之后,可能是某种性能问题?
    • 是的。我同意。请尝试将 JSON 导入部分更新为异步并检查。
    • 我该怎么做?
    猜你喜欢
    • 2018-04-02
    • 2018-01-27
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 2022-01-14
    • 2022-06-22
    • 2015-10-16
    相关资源
    最近更新 更多