使用 MERN 堆栈从服务器到客户端获取数据的错误

Posted

技术标签:

【中文标题】使用 MERN 堆栈从服务器到客户端获取数据的错误【英文标题】:Bug getting data from server to client using MERN stack 【发布时间】:2021-05-28 01:25:01 【问题描述】:

我正在构建一个 MERN Web 应用程序,但我遇到了一个错误,即当我在 clinet 端发出 get 请求时,我没有从服务器获取正确的数据。

这是来自服务器的控制器函数,用于请求 GET http://localhost:5000/public_facility/:id

export const getPublicFacilityData = async (req, res) => 
    const  id  = req.params;

    if(!mongoose.Types.ObjectId.isValid(id))
        return res.status(404).json( message: `No valid public facility id: $id`);
    

    try 
        const result = await PublicFacilityModel.findById(id, 'name data');
        res.status(200).json(result);
     catch (error) 
        res.status(500).json( message: 'Could not get public facility data');
        console.log(error);
    

这是我使用带有示例 id 的邮递员或 VS REST 客户端扩展获得的结果(与我在 MongoDB 中的数据相同):

  "result": 
    "_id": "60269642b8f3741a7c6a54ei",
    "name": "TOWN HALL",
    "data": [
      
        "year": 2019,
        "annual_data": [
          
            "consumption": [10,10,10]
            "price": [],
            "concept": "Total"
          ,
          
            "consumption": [20,20,20],
            "price": [],
            "concept": "Electricity"
          
        ]
      ,
      
        "year": 2018,
        "annual_data": [
          
            "consumption": [30,30,30],
            "price": [],
            "concept": "Total"
          
        ]
      
    ]
  

这是我从客户端发出请求的函数:

export const getPublicFacilityDatasets = async (id) => 
    if(id)
        try            
            const res = await axios.get(`http://localhost:5000/public_facility/$id`);
            
            //console.log('Result: ', res.data); 
            //console.log('Total consumption 2018', res.data.result.data[1].annual_data[0].consumption);
            ...

         catch (error) 
            ...
        
    

这是我在客户端执行请求时收到的数据:


  "result": 
    "_id": "60269642b8f3741a7c6a54ei",
    "name": "TOWN HALL",
    "data": [
      
        "year": 2019,
        "annual_data": [
          
            "consumption": [10,10,10]
            "price": [],
            "concept": "Total"
          ,
          
            "consumption": [20,20,20],
            "price": [],
            "concept": "Electricity"
          
        ]
      ,
      
        "year": 2018,
        "annual_data": [
          
            "consumption": [10,10,10],
            "price": [],
            "concept": "Total"
          
        ]
      
    ]
  

它看起来与我数据库中的数据相同,但 2018 年的总消费量 (result.data[1].annual_data[0].consumption) 具有 2019 年的总消费量值。

我发现很奇怪,如果我在请求之前执行console.log(res.data)res.data.result.data[1].annual_data[0].consumption 的值是错误的[10,10,10],但如果我执行console.log(res.data.result.data[1].annual_data[0].consumption),它会显示正确的值[30,30,30]。看起来它们不是同一个对象,但我没有任何其他名为 result 的变量。

有人有什么想法吗?如果我需要提供更多详细信息,请告诉我。

【问题讨论】:

【参考方案1】:

result.data - 数组。 您正在按索引访问数组对象,但在数组中排序是可选的。前端有几种方法可以从数组中获取数据:

    按数组搜索并按唯一元素选择
const getDataByYear = (arr,year) =>
return arr.find((x)=> x.year===year)

getDataByYear(res.data.result.data,2018)
    对从服务器接收到的数据进行归一化处理并按标识符处理。这种情况下,需要将接收到的数据带到这个表格中: 数组->对象

  "result": 
    "_id": "60269642b8f3741a7c6a54ei",
    "name": "TOWN HALL",
    "data": 
      "2019": 
        "year": 2019,
        "annual_data": [
          
            "consumption": [10,10,10]
            "price": [],
            "concept": "Total"
          ,
          
            "consumption": [20,20,20],
            "price": [],
            "concept": "Electricity"
          
        ]
      ,
      "2018": 
        "year": 2018,
        "annual_data": [
          
            "consumption": [10,10,10],
            "price": [],
            "concept": "Total"
          
        ]
      
    
  

您将访问 result.data[2018].annual_data[0].consumption 等元素

如果您没有通过单独的函数找到数组元素的索引并且不确定特定元素是否具有特定索引,则不要对数组使用索引访问。

有关数据规范化的更多信息:Redux post

测试变体

我在我的 api 上测试了相同的方案,但我使用了一些其他代码。如果你愿意,你可以试试:

export const getPublicFacilityData = async (req, res) => 
    const  id  = req.params;

    if(!mongoose.Types.ObjectId.isValid(id))
        return res.status(404).send( message: `No valid public facility id: $id`);
    

    try 
        const result = await PublicFacilityModel.findById(id, 'name data');
        res.status(200).send(result);
     catch (error) 
        res.status(500).send( message: 'Could not get public facility data');
        console.log(error);
    

export const getPublicFacilityDatasets = async (id) => 
    if(id)
        try            
            const data = await axios.get(`http://localhost:5000/public_facility/$id`);

console.log(data)
         catch (error) 
            ...
        
    

【讨论】:

感谢您的回答。我更新了我的架构以将嵌入文档放入 data,这样我就可以将 dataannual_data arreys 替换为 dicitonaies。但我仍然有同样的错误。问题是我从服务器收到的数据已经错了。 我把json改成发送 @PauCasademont 我刚刚知道问题出在 axios 接待处的解析器中。我自己使用它,看看我的 api,一切似乎都一样 一样,不过我用的是send,没有json 一开始没看到。我用 send 测试过,还是有同样的问题【参考方案2】:

我要回答我自己的问题。

与服务器请求无关的问题。我使用获得的数据来显示具有自定义图例的图表来过滤数据。问题是我将这些数据存储在一个状态变量中,当我修改它(在图表中隐藏/显示)时,它搞砸了。

如果你好奇,真正的问题是使用 chart-js-2 每个数据集都必须有一个唯一的标签。

现在它可以工作了,但我仍然不明白为什么当我 console.log() 数据时它已经错了。也许之前执行了 return 语句和渲染组件?

【讨论】:

以上是关于使用 MERN 堆栈从服务器到客户端获取数据的错误的主要内容,如果未能解决你的问题,请参考以下文章

MERN 堆栈中的 CSRF 实现

部署到 heroku - 白屏 - 没有明显错误 - MERN 堆栈在本地工作得很好,包括 API 请求 - 已经尝试了 27 次部署

使用 Postman MERN 堆栈在发布请求上收到 404 错误

如何在 MERN 堆栈中向用户显示错误

如何在 mern 堆栈中获取注册表单的国家/地区列表?

如何使用 MERN 堆栈构建动态单页 Web 应用程序?