无法从Javascript中的对象访问属性

时间:2020-05-30 22:08:43

标签: javascript node.js sequelize.js

编辑:重新构造了问题,思路和思路:

我有一个来自Sequelize的$Attendedby = implode(', ', $_POST['Attendedby']); 对象,它是由node-express发送的:

data

BIG问题是,如何获取{ "page": 0, "limit": 10, "total": 4, "data": [ { "id": 1, "title": "movies", "isActive": true, "createdAt": "2020-05-30T19:26:04.000Z", "updatedAt": "2020-05-30T19:26:04.000Z", "questions": [ { "questionsCount": 4 } ] } ] } 的值? 问题是,我只是无法提取它,这两种方法给了我questionsCount结果:

  1. undefined
  2. category.questions[0].questionsCount

我可以使用category.questions[0]['questionsCount'](我认为是从Sequelize lib中获得它),就像这样:

toJSON()

但是我想知道问题的答案,或者至少清楚地说明了为什么我仅为了获得category.questions[0].toJSON().questionsCount 而必须使用toJSON()吗?


更多内容:

我的控制器中有这个questionsCount

GET

我遍历exports.getCategories = (req, res) => { const page = myUtil.parser.tryParseInt(req.query.page, 0) const limit = myUtil.parser.tryParseInt(req.query.limit, 10) db.Category.findAndCountAll({ where: {}, include: [ { model: db.Question, as: "questions", attributes: [[db.Sequelize.fn('COUNT', 'id'), 'questionsCount']] } ], offset: limit * page, limit: limit, order: [["id", "ASC"]], }) .then(data => { data.rows.forEach(function(category) { console.log("------ May 31 ----> " + JSON.stringify(category.questions[0]) + " -->" + category.questions[0].hasOwnProperty('questionsCount')) console.log(JSON.stringify(category)) console.log(category.questions[0].toJSON().questionsCount) }) res.json(myUtil.response.paging(data, page, limit)) }) .catch(err => { console.log("Error get categories: " + err.message) res.status(500).send({ message: "An error has occured while retrieving data." }) }) } 以获取每个data.rows对象。

category的输出是:

console.log

4 个答案:

答案 0 :(得分:1)

尝试

category.data[0].questions[0].questionCount

必须使用toJSON的原因是因为它有时用于自定义字符串化行为。就像在将值赋给将要返回的对象之前进行一些计算一样,因此在这里最常使用likley来计算“问题的数量”,然后返回具有属性questionscount和计算出的数量的对象 因此,您或多或少取回的对象看起来像这样

var cathegory = {
  data: 'data',
  questions:[{
    // some calulation here to get the questionsCount 
      result=4,
    toJSON () {
      return  {"questionsCount":this.result}       
    } 
  }
 ]
};

console.log(cathegory.questions[0].toJSON().questionsCount) //4
console.log(JSON.stringify(cathegory))  // {"data":"data","questions":[{"questionsCount":4}]}
console.log("------ May 31 ----> " + JSON.stringify(cathegory.questions[0]) + " -->" + cathegory.questions[0].hasOwnProperty('questionsCount')) //false

答案 1 :(得分:1)

尝试这样做category.data[0].questions.questionCount

答案 2 :(得分:1)

正如其他人已经提到的那样,您需要category.data[0].questions[0].questionCount

让我通过显示原因来补充一下。看看您的对象,我用如何访问每个部分的方式对其进行了注释:

category = { // category
    "page": 0,
    "limit": 10,
    "total": 2,
    "data": [ // category.data
        { // category.data[0]
            "id": 1,
            "title": "movies",
            "createdAt": "2020-05-30T19:26:04.000Z",
            "updatedAt": "2020-05-30T19:26:04.000Z",
            "questions": [ // category.data[0].questions
                { // category.data[0].questions[0]
                    "questionCount": 2 // category.data[0].questions[0].questionCount
                }
            ],
            "questionsCount": "newValue here!"
        }
    ]
}

答案 3 :(得分:1)

https://github.com/sequelize/sequelize/blob/master/docs/manual/core-concepts/model-querying-finders.md

默认情况下,所有finder方法的结果都是模型类的实例(而不只是纯JavaScript对象)。这意味着在数据库返回结果之后,Sequelize会自动将所有内容包装在适当的实例对象中。在少数情况下,当结果太多时,这种包装可能会效率低下。要禁用此包装并接收普通响应,请将{raw:true}作为选项传递给finder方法。

(我强调)
或直接在源代码中,https://github.com/sequelize/sequelize/blob/59b8a7bfa018b94ccfa6e30e1040de91d1e3d3dd/lib/model.js#L2028

@返回{Pr​​omise <{count:数字,行:Model []}>}

所以事情是,您获得了Model个对象的数组,可以使用它们的get()方法进行导航。不幸的巧合是,您期望有一个数组,并且得到了一个数组,因此您认为它是“那个”数组。试试{raw:true},我想看起来像这样:

db.Category.findAndCountAll({
    where: {},
    include: [
      {
        model: db.Question,
        as: "questions",
        attributes: [[db.Sequelize.fn('COUNT', 'id'), 'questionsCount']]
      }
    ],
    offset: limit * page,
    limit: limit,
    order: [["id", "ASC"]],
    raw: true                            // <--- hopefully it is this simple
  }) [...]


toJSON()也在附近,https://github.com/sequelize/sequelize/blob/59b8a7bfa018b94ccfa6e30e1040de91d1e3d3dd/lib/model.js#L4341

  /**
   * Convert the instance to a JSON representation.
   * Proxies to calling `get` with no keys.
   * This means get all values gotten from the DB, and apply all custom getters.
   *
   * @see
   * {@link Model#get}
   *
   * @returns {object}
   */
  toJSON() {
    return _.cloneDeep(
      this.get({
        plain: true
      })
    );
  }

它之所以起作用,完全是因为它做了您需要的事情,删除了get()东西,并提供了一个与您的结构相匹配的实际JavaScript对象(PO​​JSO?–对不起,我无法抗拒)。我很少使用它,因此总是会忘记,但是关键的背景“技巧”是有点与它的名称相反,toJSON()不能创建实际的JSON字符串,而是提供仍然被字符串化的替换对象由JSON.stringify()。 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON_behavior