列表视图抛出 TypeError
List view throwing TypeError
您的预期:
刚刚完成教程(成功)并尝试修改代码以使用我的 API。列表视图未显示数据且控制台有错误。
我能够添加 API 登录调用,在列表视图中我可以看到我的 API 已成功调用。
发生了什么:
页面显示标题和 "No results found"
控制台错误
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)
API 来自 DevTools 的响应数据(无法弄清楚如何格式化数据,所以它是一个屏幕截图。)
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"
}
]
}
回应Headers
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 个附加字段 ("success": true)。我删除了它但得到了相同的结果。
其他信息:
环境
- React-admin版本:2.1.2
- 没有出现问题的最后一个版本(如果适用):N/A
- 反应版本:16.4.1
- 浏览器:Chrome/OSX
- 堆栈跟踪(如果出现 JS 错误):以上
您的 API 的输出仍然不是立即数组。要么你改变你的 API 或者你改变你的 dataProvider.
选项 A:server-side 解决方案
改变你的API输出:
[
{
"id": 1,
"status": "DRAFT"
},
{
"id": 2,
"status": "DRAFT"
},
...
]
如果您利用可以告诉客户端服务器是否成功的 HTTP 状态(200、404、500),则不需要成功 属性* , ETC)。您也不需要总数 属性,因为您的 API 在 Content-range 响应 header.[=17= 中已经是 telling ]
Content-range: matches 0-5/5
^ total
选项 B. client-side 解决方案
您可能正在使用某种形式的数据提供者,它是 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 客户端,您可能习惯于发送成功属性。我知道我是。
您的预期: 刚刚完成教程(成功)并尝试修改代码以使用我的 API。列表视图未显示数据且控制台有错误。
我能够添加 API 登录调用,在列表视图中我可以看到我的 API 已成功调用。
发生了什么: 页面显示标题和 "No results found"
控制台错误
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)
API 来自 DevTools 的响应数据(无法弄清楚如何格式化数据,所以它是一个屏幕截图。)
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"
}
]
}
回应Headers
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 个附加字段 ("success": true)。我删除了它但得到了相同的结果。
其他信息:
环境
- React-admin版本:2.1.2
- 没有出现问题的最后一个版本(如果适用):N/A
- 反应版本:16.4.1
- 浏览器:Chrome/OSX
- 堆栈跟踪(如果出现 JS 错误):以上
您的 API 的输出仍然不是立即数组。要么你改变你的 API 或者你改变你的 dataProvider.
选项 A:server-side 解决方案
改变你的API输出:
[
{
"id": 1,
"status": "DRAFT"
},
{
"id": 2,
"status": "DRAFT"
},
...
]
如果您利用可以告诉客户端服务器是否成功的 HTTP 状态(200、404、500),则不需要成功 属性* , ETC)。您也不需要总数 属性,因为您的 API 在 Content-range 响应 header.[=17= 中已经是 telling ]
Content-range: matches 0-5/5
^ total
选项 B. client-side 解决方案
您可能正在使用某种形式的数据提供者,它是 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 客户端,您可能习惯于发送成功属性。我知道我是。