Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过express从mongo获取数据、构建对象并发送到React_Javascript_Node.js_Reactjs_Mongodb_Express - Fatal编程技术网

Javascript 通过express从mongo获取数据、构建对象并发送到React

Javascript 通过express从mongo获取数据、构建对象并发送到React,javascript,node.js,reactjs,mongodb,express,Javascript,Node.js,Reactjs,Mongodb,Express,我现在被困在地狱里。 在React中,我有一个页面/菜单,可以通过ExpressJSAPI从我的mongo实例加载数据 在我的名为“菜单”的数据库中,我有代表膳食类型的集合,如“早餐”、“午餐”等。在这些集合中,每个项目的文档都类似于以下面包集合示例: { _id: 2398jcs9dn2f9f, name: "Ciabatta", desc: "Italian bread", imageURI: "image01.jpg&quo

我现在被困在地狱里。 在React中,我有一个页面/菜单,可以通过ExpressJSAPI从我的mongo实例加载数据

在我的名为“菜单”的数据库中,我有代表膳食类型的集合,如“早餐”、“午餐”等。在这些集合中,每个项目的文档都类似于以下面包集合示例:

{
  _id: 2398jcs9dn2f9f,
  name: "Ciabatta",
  desc: "Italian bread",
  imageURI: "image01.jpg",
  reviews: []
}
这是我的api,当页面加载时将调用它

exports.getAllFoods = (req, res, next) => {
    const db = mongoose.connection

    const allCollections = {}

    try {
        db.db.listCollections().toArray((err, collections) => {
            collections.forEach((k) => {
                allCollections[k.name] = []
            })

            Object.keys(allCollections).map(k => {
                let Meal = mongoose.model(k, MealSchema)
            
                meal = Meal.find((err, docs) => {
                    allCollections[k] = docs
                    console.log(allCollections)
                })
            })
            res.send(allCollections)
        })
    } catch (error) {
        console.log(error)
        res.send('unable to get all collections')
    }
}
console.log(allCollections)的最后一个输出生成以下内容:

{ snacks:
   [ { review: [],
       tags: [],
       _id: 5fcec3fc4bc5d81917c9c1fe,
       name: 'Simosa',
       description: 'Indian food',
       imageURI: 'image02.jpg',
       __v: 0 } ],
  breads:
   [ { review: [],
       tags: [],
       _id: 5fcec41a4bc5d81917c9c1ff,
       name: 'Ciabatta',
       description: 'Italian bread',
       imageURI: 'image02.jpg',
       __v: 0 } ],
}
这正是我所需要的,但我一直在思考如何发送邮件以作出反应。我该如何发送上述json?res.send(allCollections)为我提供了以下信息:

{
    "snacks": [],
    "breads": [],
    "drinks": []
}
我理解为什么会发送上述信息,但我不知道我需要做些什么来解决它

这是我对页面加载的反应

useEffect(() => {
        axios
        .get('http://localhost:8888/api/allFoods')
        .then((res) => {
            setMealTypes(res.data)
        })
        .catch((err) => [
            console.log(err)
        ])
    }, [])
最终,我需要在控制台中输出json,因为我希望循环遍历该数据并使用该键作为标题,然后列出值数组中的值

<div>
  <h2>Breads</h2>
  <img src=image01.jpg/>
  <h3>Ciabatta</h3>
  <p>Italian bread</p>
  ...
</div> 
...

面包
西亚巴塔
意大利面包

... ...

我非常感谢任何帮助,以及我应该阅读的任何文档,以帮助和提高我对javascript的理解

我希望这将对您有所帮助:在从express api发送集合之前,您需要首先使用stringify方法,然后在React前端使用JSON.parse来恢复对象。
PS:您能在res.send(allCollections)上方一行执行console.log(allCollections)吗?

您需要以JSON格式将其发送到前端


res.send(allCollections)
替换为
res.json(allCollections)
我更喜欢使用
async
/
wait
Promise.all
,替换大多数回调

因为在遍历数组时调用DB,所以有一种最烦人的回调情况:如何发出一堆异步消息,然后再得到结果?在发送结果之前,您需要一些其他的东西来确保调用所有回调

Async/await意味着我们可以声明函数是异步的,并等待异步操作的结果。async/await在JS中很烦人,因为它抽象掉回调,实际上在下面创建了一个承诺。使事情进一步复杂化的是,async/await不能解决发出多个异步函数的问题,因此我们必须再次依赖这个奇特的
Promise.all()
函数与
map
-将所需的输入数组映射为异步函数

原件:

Object.keys(所有集合).map(k=>{
让膳食=猫鼬。模型(k,MealSchema)
膳食=膳食。查找((错误,文档)=>{
所有集合[k]=单据
console.log(所有集合)
})
});
建议异步/等待:

wait Promise.all(Object.key(allCollections.map)(异步k=>{
让膳食=猫鼬。模型(k,MealSchema)
let docs=等待用餐。find();
所有集合[k]=单据;
console.log(所有集合);
}));
另一个优点是错误处理。如果在原始示例的回调中发生任何错误,它们将不会被捕获在此try/catch块中。 async/await会像您预期的那样处理错误,错误最终会出现在catch块中

。。。
//现在我们已经等待了上面所有的异步调用,应该在异步调用之后而不是之前执行。
res.send(所有集合);
})
}捕获(错误){
console.log(错误)
res.send('无法获取所有集合')
}
}
从技术上讲,
Promise.all()
返回一个结果数组,但是我们可以忽略它,因为您正在格式化一个
对象

这方面还有很多进一步优化的空间。我可以将整个函数编写为:

exports.getAllFoods=async(请求、回复、下一步)=>{
const db=mongoose.connection.db;
试一试{
let collections=wait db.listCollections().toArray();
让所有集合={};
集合。forEach((k)=>{
所有集合[k.name]=[];
})
//对于每个集合键名称,从数据库中查找文档
//在继续下一个块之前,等待此块完成
等待Promise.all(Object.keys(allCollections.map)(异步k=>{
让膳食=猫鼬。模型(k,MealSchema)
let docs=等待用餐。find();
所有集合[k]=单据;
}));
//如果未发生错误,则应填充所有集合
console.log(所有集合);
res.send(所有集合);
}捕获(错误){
console.log(错误)
res.send('无法获取所有集合')
}
}
完全未经测试

您可能会发现这些链接比我的解释更有帮助:


非常感谢。这解决了我的问题。正如您所说,这允许在发送我的请求之前完成所有回调。非常感谢。为了更好地理解async/await,我将浏览这些资源