【问题标题】:List view throwing TypeError列表视图抛出 TypeError
【发布时间】:2018-07-20 17:34:58
【问题描述】:

你所期待的: 刚刚完成教程(成功)并尝试修改代码以使用我的 API。列表视图未显示数据且控制台出现错误。

我能够添加用于登录的 API 调用,并且在列表视图中我可以看到我的 API 已成功调用。

发生了什么事: 页面显示标题和“未找到结果”

控制台错误

index.js:2178 uncaught at handleFetch TypeError: newRecords.map is not a function
    at http://localhost:3001/static/js/bundle.js:69772:52
    at http://localhost:3001/static/js/bundle.js:69828:24
    at http://localhost:3001/static/js/bundle.js:69917:40
    at Array.reduce (<anonymous>)
    at ./node_modules/ra-core/lib/reducer/admin/resource/index.js.exports.default (http://localhost:3001/static/js/bundle.js:69914:30)
    at combination (http://localhost:3001/static/js/bundle.js:134671:29)
    at combination (http://localhost:3001/static/js/bundle.js:134671:29)
    at resettableAppReducer (http://localhost:3001/static/js/bundle.js:63329:16)
    at dispatch (http://localhost:3001/static/js/bundle.js:134907:22)
    at http://localhost:3001/static/js/bundle.js:119507:18
    at http://localhost:3001/static/js/bundle.js:132848:22
    at dispatch (http://localhost:3001/static/js/bundle.js:134462:18)
    at http://localhost:3001/static/js/bundle.js:134352:12
    at http://localhost:3001/static/js/bundle.js:133375:52
    at exec (http://localhost:3001/static/js/bundle.js:134015:5)
    at flush (http://localhost:3001/static/js/bundle.js:134056:5)
    at asap (http://localhost:3001/static/js/bundle.js:134029:5)
    at runPutEffect (http://localhost:3001/static/js/bundle.js:133372:69)
    at runEffect (http://localhost:3001/static/js/bundle.js:133321:307)
    at next (http://localhost:3001/static/js/bundle.js:133201:9)
    at currCb (http://localhost:3001/static/js/bundle.js:133274:7)

来自 DevTools 的 API 响应数据(无法弄清楚如何格式化数据,所以它是一个屏幕截图。)

来自 Postman 的 API 响应

{
"matches": [
    {
        "id": 1,
        "status": "DRAFT"
    },
    {
        "id": 2,
        "status": "DRAFT"
    },
    {
        "id": 3,
        "status": "DRAFT"
    },
    {
        "id": 4,
        "status": "READY"
    },
    {
        "id": 5,
        "status": "DRAFT"
    },
    {
        "id": 6,
        "status": "DRAFT"
    },
    {
        "id": 7,
        "status": "DRAFT"
    }
]

}

响应标头

Access-Control-Allow-Origin: * 
Access-Control-Expose-Headers: Content-Range 
Connection: keep-alive 
content-range: matches 0-5/5 
Date: Fri, 20 Jul 2018 16:33:12 GMT 
ETag: W/"a5-KZYtsf9f1aSutDA6i7vGzddXNZk" 
X-Powered-By: Express 

Matches.js 代码

import React from 'react';
import { List, Edit, Create, Datagrid, ReferenceField, TextField, EditButton, DisabledInput, LongTextInput, ReferenceInput, SelectInput, SimpleForm, TextInput } from 'react-admin';

export const MatchList = (props) => (
    <List {...props}>
        <Datagrid>
            <TextField source="id" />
            <TextField source="status" />
        </Datagrid>
    </List>
);

本教程使用的是虚拟 api,我切换到 ra-data-simple-rest。我不得不对我的 API 输出进行一些更改以匹配预期的格式,所以我猜这可能是问题的根源,但该错误没有帮助。

我原来有很多列,有些是空的,所以我只留下了 ID 和状态。我的结果中确实返回了 1 个附加字段(“成功”:true)。我删除了它,但得到了相同的结果。

其他信息:

环境

  • React-admin 版本:2.1.2
  • 未出现此问题的最新版本(如果适用):不适用
  • 反应版本:16.4.1
  • 浏览器:Chrome/OSX
  • 堆栈跟踪(在 JS 错误的情况下):以上

【问题讨论】:

  • 请告诉我你的数据休息提供者。管理组件应将其实现为 dataProvider。 marmelab.com/react-admin/DataProviders.html
  • 你问我使用的是什么数据提供者?这是 ra-data-simple-rest。我正在尝试调整我的 API 输出以匹配它期望的结果。从 'ra-data-simple-rest' 导入 simpleRestProvider;

标签: react-admin


【解决方案1】:

您的 API 的输出仍然不是直接数组。要么多修改 API,要么修改 dataProvider

选项 A:服务器端解决方案

更改您的 API 以输出:

[
    {
        "id": 1,
        "status": "DRAFT"
    },
    {
        "id": 2,
        "status": "DRAFT"
    },
    ...
]

如果您利用可以告诉客户端服务器是否成功(200、404、500 等)的 HTTP 状态,则不需要成功属性*。您也不需要 total 属性,因为您的 API 已经是 telling 在 Content-range 响应标头中的客户端。

Content-range: matches 0-5/5
                           ^ total

选项 B. 客户端解决方案

您可能正在使用某种形式的 Dataprovider,它是一个 ra-something-client。它可能有一个看起来与此相似的部分。

const convertHTTPResponseToREST = (response, type, resource, params) => {
    const { headers, json } = response;

    switch (type) {
        case GET_LIST:
        case GET_MANY_REFERENCE: {
            if (!headers.has('content-range')) {
                throw new Error(
                    'The Content-Range header is missing in the HTTP Response. ' +
                        'The PostgREST client expects responses for lists of resources to contain ' +
                        'this header with the total number of results to build the pagination. ' +
                        'If you are using CORS, did you declare Content-Range in the ' +
                        'Access-Control-Expose-Headers header?'
                );
            }
            return {
                data: json.slice(),
                total: parseInt(
                    headers
                        .get('content-range')
                        .split('/')
                        .pop(),
                    10
                ),
            };
        }
        case CREATE:
            return { data: { ...params.data, id: json.id } };
        case DELETE:
            return { data: {} };
        default:
            return { data: json };
    }
};

您可以将其中的一部分更改为:

return {
    data: json.data.slice(),
    total: json.total || parseInt(
        headers
            .get('content-range')
            .split('/')
            .pop(),
        10
    ),
};

或者只是:

return json;

* 由于某些 Sencha/Ext JS 客户端,您可能习惯于发送成功属性。我知道我是。

【讨论】:

  • 我不知道你为什么说我的输出不是一个数组。 Github 上的 fzaninotto 也说了同样的话。我会将我当前的 API 输出添加到原始评论中。对不起,令人困惑的评论。当我想换行时输入提交。
  • 我的输出有一个数组。根据您的 cmets,我进行了一些更改,结果相同:1)从输出中删除了总计,2)从输出中删除了状态并将数据更改为匹配项。我真的希望#3 是我的问题。文档将“数据”显示为数组之前的名称,但是当我查看简单示例时,我可以看到它是对象名称。文档中没有说明,但数据数组名称、App.js 中的资源名称和 Content Range 标头中的元数据似乎都应该相同。对吗?
  • 仔细阅读我的话。您的输出仍然不是数组。它在您的datamatches 属性中有一个数组,但它仍然不是一个数组。数组必须是您的 API 中最先出现的东西。这意味着输出以[ 而不是{ 开头。或者按照我的回答更改您的数据提供者。
  • 搞定了。抱歉,如果我似乎没有阅读您的答案。我只是在解释文档所说的内容。在marmelab.com/react-admin/DataProviders.html#response-format,似乎说我的 API 响应应该是一个嵌入了数组的对象。
  • 我将尝试为该项目做出贡献。我可以通过我的虚拟镜头查看文档来帮助改进文档。真的很高兴能开始使用它,因为我很高兴能开始使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
  • 2013-07-05
  • 1970-01-01
  • 2011-10-03
  • 2016-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多