【问题标题】:recursive function is not returning value in express js?递归函数在express js中没有返回值?
【发布时间】:2021-11-07 10:51:29
【问题描述】:

我在电子商务网站工作。我已经为所有类别创建了一个猫鼬模型。但包括作为子类别的类别的父 ID。 当收到请求发送时,所有类别都是从数据库中找到的。很好,但我想以嵌套的方式将类别发送给客户端。这就是我这样写的原因。

// This is mongoose model 


const mongoose = require('mongoose');

const categorySchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        trim: true,
        unique: true
    },
    slug: {
        type: String,
        required: true,
        unique: true
    },
    parentId: {
        type: mongoose.Schema.Types.ObjectId
    }

}, { timestamps: true })

module.exports = mongoose.model("Category", categorySchema)



//   This is router


Router.get('/categories', async (req, res) => {


    const createCategory = (categories, parentId = null) => {

        const categoryList = []
        let category

        if (parentId === null) {
            category = categories.filter(cat => cat.parentId === undefined);
        } else {
            category = categories.filter(cat => cat.parentId === parentId)
        }

        category.map((cate) => {
            categoryList.push({
                _id: cate._id,
                name: cate.name,
                slug: cate.slug,
                children: createCategory(categories, cate._id)
            })
        })


        return categoryList
    }

    try {

        const categories = await Category.find({})

        const categoryList = createCategory(categories)

        res.status(200).json({ categoryList })

    } catch (error) {

        res.status(500).json(error)
    }
})

  // the data of databess
  
  [
  {
    _id: new ObjectId("613c4ae2ff0098e41b1ae89a"),
    name: 'Mobile',
    slug: 'Mobile',
    createdAt: 2021-09-11T06:21:22.137Z,
    updatedAt: 2021-09-11T06:21:22.137Z,
    __v: 0
  },
  {
    _id: new ObjectId("613c4b11ff0098e41b1ae89c"),
    name: 'Oppo',
    slug: 'Oppo',
    parentId: '613c4ae2ff0098e41b1ae89a',
    createdAt: 2021-09-11T06:22:09.068Z,
    updatedAt: 2021-09-11T06:22:09.068Z,
    __v: 0
  },
  {
    _id: new ObjectId("613c4b21ff0098e41b1ae89e"),
    name: 'Samsung',
    slug: 'Samsung',
    parentId: '613c4ae2ff0098e41b1ae89a',
    createdAt: 2021-09-11T06:22:25.359Z,
    updatedAt: 2021-09-11T06:22:25.359Z,
    __v: 0
  },
  {
    _id: new ObjectId("613c4b2fff0098e41b1ae8a0"),
    name: 'Nokia',
    slug: 'Nokia',
    parentId: '613c4ae2ff0098e41b1ae89a',
    createdAt: 2021-09-11T06:22:39.048Z,
    updatedAt: 2021-09-11T06:22:39.048Z,
    __v: 0
  },
  {
    _id: new ObjectId("613c4b47ff0098e41b1ae8a2"),
    name: 'Nokia 2.4',
    slug: 'Nokia-2.4',
    parentId: '613c4ae2ff0098e41b1ae89a',
    createdAt: 2021-09-11T06:23:03.580Z,
    updatedAt: 2021-09-11T06:23:03.580Z,
    __v: 0
  },
  {
    _id: new ObjectId("613c4b6cff0098e41b1ae8a4"),
    name: 'TV',
    slug: 'TV',
    createdAt: 2021-09-11T06:23:40.550Z,
    updatedAt: 2021-09-11T06:23:40.550Z,
    __v: 0
  },
  {
    _id: new ObjectId("613c4b7eff0098e41b1ae8a6"),
    name: 'Refrijerator',
    slug: 'Refrijerator',
    createdAt: 2021-09-11T06:23:58.782Z,
    updatedAt: 2021-09-11T06:23:58.782Z,
    __v: 0
  }
]

他们的问题是当我试图从客户端获取数据时,只有根级别的类别正在输出,它没有父 ID,但子数组是这样的空。

{
    "categoryList": [
        {
            "_id": "613c4ae2ff0098e41b1ae89a",
            "name": "Mobile",
            "slug": "Mobile",
            "children": []
        },
        {
            "_id": "613c4b6cff0098e41b1ae8a4",
            "name": "TV",
            "slug": "TV",
            "children": []
        },
        {
            "_id": "613c4b7eff0098e41b1ae8a6",
            "name": "Refrijerator",
            "slug": "Refrijerator",
            "children": []
        }
    ]
}

我认为“createCategory”递归函数不起作用。

请任何人帮助我,我是这个领域的新手......

【问题讨论】:

  • 如果你没有使用.map()的结果,你应该使用.forEach()
  • 我无法重现此问题。当我尝试填充 children 数组时。 categories 是什么?您能否编辑您的问题并为categories 提供示例数据(JSON 格式),这会给您带来这种不希望的结果?
  • 如果你写categoryList = category.map(cate => ...),你可以使用.map(),并让函数返回对象而不是推送它。
  • 请输出console.log(JSON.stringify(categories, null, 2)) 并将其包含在您的问题中。我想_id 值是对象,而不是字符串(您似乎假设)。但请提供它,以便我们重现您的问题。

标签: javascript node.js express mongoose


【解决方案1】:

由于_id 属性是ObjectId 的实例,它们永远不会与parentId 匹配,后者是字符串。

根据documentation

ObjectId()具有以下属性和方法:

Attribute/Method Description
str Returns the hexadecimal string representation of the object.
... ...

所以改变这一行:

        children: createCategory(categories, cate._id)

到:

        children: createCategory(categories, cate._id.str)

备注

您对.map 的使用是一种反模式。您应该获取它的返回值,而不是在回调中使用push。替换这两个语句:

    const categoryList = []
    /* .. */
    category.map((cate) => {
        categoryList.push({
            _id: cate._id,
            name: cate.name,
            slug: cate.slug,
            children: createCategory(categories, cate._id.str)
        })
    })

...用这个单一的语句:

    const categoryList = category.map((cate) => ({
        _id: cate._id,
        name: cate.name,
        slug: cate.slug,
        children: createCategory(categories, cate._id.str)
    }))

其次,您可以通过parentId 参数提供默认值来避免函数开头的代码重复。所以这个函数可以变得更加紧凑:

const createCategory = (categories, parentId) => {
    const category = categories.filter(cat => cat.parentId === parentId);
    return category.map((cate) => ({
        _id: cate._id,
        name: cate.name,
        slug: cate.slug,
        children: createCategory(categories, cate._id.str)
    }));
};

【讨论】:

  • 全部替换后我得到一个空数组。有什么事要做吗?
  • 是的,根据我在您问题下方的评论采取行动。
  • 感谢“trincot”给我一个线索,我通过你的线索找到了。 “cate._id”将是“cate._id.toString()”
  • 不客气。但是,如果这不起作用,则意味着您的 cate._id 不是您的问题中描述的 ObjectId 实例。如果您能对我对您的问题的评论做出反应,那就太好了:/
  • 对不起,我是新手,我不知道如果我选择另一个标记会改变。我以为两者都会被标记。我想你已经明白了。
【解决方案2】:

修改下面的代码

 children: createCategory(categories, cate._id)

收件人:

children: createCategory(categories, cate._id.toString())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 2022-11-05
    • 2020-10-10
    • 2021-06-11
    • 2012-03-11
    相关资源
    最近更新 更多