Reputation: 315
What you were expecting: Just went through the tutorial (successfully) and tried to modify code to use my API. List view is not showing data and console has error.
I was able to add the API call for login and on the list view I can see my API is successfully called.
What happened instead: Page shows title and "No results found"
Console error
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 Response Data from DevTools (Couldn't figure out how to format the data so it's a screen cap.)
API Response from Postman
{
"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"
}
]
}
Response 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 code
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>
);
The tutorial was using the dummy api and I switched to ra-data-simple-rest. I had to make a few changes to my API output to match the format expected, so I'm guessing this might be the source of the problem, but the error is not helpful.
I originally had many columns and some were null, so I just left ID and Status. I do have 1 additional field returned in my results ("success": true). I removed that but got the same results.
Other information:
Environment
Upvotes: 2
Views: 1324
Reputation: 11137
The output of your API is still not an immediate array. Either you alter your API a bit more or you alter your dataProvider.
Option A: The server-side solution
Alter your API to output:
[
{
"id": 1,
"status": "DRAFT"
},
{
"id": 2,
"status": "DRAFT"
},
...
]
You don't need the success property* if your leveraging HTTP statuses that can tell the client whether the server succeeded or not (200, 404, 500, etc). You also don't need the total property, since your API is already telling that to the client in the Content-range response header.
Content-range: matches 0-5/5
^ total
Option B. The client-side solution
You're probably using some form of a Dataprovider which is a ra-something-client. It probably has a part that looks similar to this.
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 };
}
};
You can change a part of it to:
return {
data: json.data.slice(),
total: json.total || parseInt(
headers
.get('content-range')
.split('/')
.pop(),
10
),
};
Or just:
return json;
* You may be used to sending the success property due to some Sencha/Ext JS clients. I know I was.
Upvotes: 1