列表视图抛出TypeError

时间:2018-07-20 17:34:59

标签: react-admin

您的期望: 刚刚(成功)完成了本教程,并尝试修改代码以使用我的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响应数据(无法弄清楚如何格式化数据,因此它是屏幕截图。) API Response

邮递员的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和Status。我的结果中确实返回了1个其他字段(“成功”:是)。我删除了,但是得到了相同的结果。

其他信息:

环境

  • 反应管理员版本:2.1.2
  • 没有出现此问题的最新版本(如果有):N / A
  • 反应版本:16.4.1
  • 浏览器:Chrome / OSX
  • 堆栈跟踪(如果发生JS错误):以上

1 个答案:

答案 0 :(得分:1)

您的API的输出仍然不是立即数组。您可以更改API一点,也可以更改dataProvider

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

更改您的API以输出:

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

如果您利用HTTP状态可以告诉客户端服务器是否成功(200、404、500等),则不需要成功属性 * 。您也不需要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客户端,您可能习惯于发送成功属性。我知道我是。