In an react-admin 3.2.3 edit form I need to show related records (the list of job records) from a different resource. The relation is a bit weird and requires string parsing so I can't just use the built-in ReferenceField
. That's why I am trying to call the dataProvider's getList
function using the useGetList
hook. Unfortunately I get an error on form rendering:
The dataProvider threw an error. It should return a rejected Promise instead
This is the getList function of my custom dataprovider:
getList: (resource, params) => {
console.log('DataProvider.GetList ');
console.log(resource);
console.log(params);
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
...fetchUtils.flattenObject(params.filter),
_sort: field,
_order: order,
_start: (page - 1) * perPage,
_end: page * perPage,
};
const url = `${getUrl(resource)}?${stringify(query)}`;
const paging = supportsPaging(resource);
return httpClient(url).then(
({ headers, json }) => {
var result = [];
// Implementierung von clientseitigem Paging & Filtering
var filtered = applyFilter(json, params.filter);
if (!paging) {
filtered=applyPagination(filtered, page, perPage);
}
else {
result = filtered;
}
return {
data: result,
total: json.length
};
}, ({ reason }) => {
console.log(reason);
}).catch((e)=>{
console.log(e);
});
}
I use this custom ponent in the edit form.
export const CSEJobList = ({ ...props }) => {
const form = useForm();
var formdata = form.getState().values;
console.log("CSEJobList");
if (formdata && formdata.status && formdata.status.id >= 2) {
var data = GetJobData({ 'filter': { type: 'abeitsschein_id_' + formdata.id } });
return data;
}
else {
return <div>Test</div>
}
};
CSEJobList.defaultProps = { label: 'Arbeitsschein', addLabel: true };
const GetJobData = (params) => {
let parms = { "pagination": { "page": 0, "perPage": 25 }, "sort": { "field": "id", "order": "ASC" }, "filter": {} };
const { data, loading, error } = useGetList('jobs', parms);
if (loading) { return <LinearProgress />; }
if (error) { return <p>ERROR</p>; }
return <p>{data}</p>;
};
This is just a basic test. Proper display of result data is not implemented yet since the call results in the mentioned error.
I read the documentation (.html#specialized-hooks) about querying the API, fiddled around a lot, but I fail because of my limited understanding of promises.
Is there an easy fix?
Update:
I changed the dataProvider getList
function like so, return rejected promises as suggested:
getList: (resource, params) => {
console.log('DataProvider.GetList ');
console.log(resource);
console.log(params);
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
...fetchUtils.flattenObject(params.filter),
_sort: field,
_order: order,
_start: (page - 1) * perPage,
_end: page * perPage,
};
const url = `${getUrl(resource)}?${stringify(query)}`;
const paging = supportsPaging(resource);
return httpClient(url).then(
({ headers, json }) => {
var result = [];
// Implementierung von clientseitigem Paging & Filtering
var filtered = applyFilter(json, params.filter);
if (!paging) {
filtered=applyPagination(filtered, page, perPage);
}
else {
result = filtered;
}
return {
data: result,
total: json.length, // Erfordert nun keinen speziellen Header mehr, CSE-Connect kompatibel
};
}, ({ reason }) => {
return Promise.reject(reason);
}).catch((e)=>{
console.log(e);
return Promise.reject(e);
});
},
It had no effect. After some debugging I realized that in the GetJobData
function the line
if (loading) { return <LinearProgress />; }
causes the error. Exactly the same works in other parts of the code, so the suspect is not LinearProgress
. I actually have no Idea what causes the error. Debugging is hard to impossible because of timeouts.
This is the full stack trace:
useDataProvider.js:334 Uncaught Error: The dataProvider threw an error. It should return a rejected Promise instead.
at performQuery (useDataProvider.js:334)
at Proxy.<anonymous> (useDataProvider.js:163)
at JSON.stringify.query (useQueryWithStore.js:116)
at mitHookEffectList (react-dom.development.js:22030)
at mitPassiveHookEffects (react-dom.development.js:22064)
at HTMLUnknownElement.callCallback (react-dom.development.js:336)
at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
at invokeGuardedCallback (react-dom.development.js:440)
at flushPassiveEffectsImpl (react-dom.development.js:25392)
at unstable_runWithPriority (scheduler.development.js:697)
at runWithPriority$2 (react-dom.development.js:12149)
at flushPassiveEffects (react-dom.development.js:25361)
at performSyncWorkOnRoot (react-dom.development.js:24251)
at react-dom.development.js:12199
at unstable_runWithPriority (scheduler.development.js:697)
at runWithPriority$2 (react-dom.development.js:12149)
at flushSyncCallbackQueueImpl (react-dom.development.js:12194)
at flushSyncCallbackQueue (react-dom.development.js:12182)
at batchedUpdates$1 (react-dom.development.js:24392)
at Object.notify (Subscription.js:19)
at Subscription.notifyNestedSubs (Subscription.js:92)
at Subscription.handleChangeWrapper (Subscription.js:97)
at dispatch (redux.js:222)
at middleware.js:22
at redux-saga-core.esm.js:1410
at useDataProvider.js:300
In an react-admin 3.2.3 edit form I need to show related records (the list of job records) from a different resource. The relation is a bit weird and requires string parsing so I can't just use the built-in ReferenceField
. That's why I am trying to call the dataProvider's getList
function using the useGetList
hook. Unfortunately I get an error on form rendering:
The dataProvider threw an error. It should return a rejected Promise instead
This is the getList function of my custom dataprovider:
getList: (resource, params) => {
console.log('DataProvider.GetList ');
console.log(resource);
console.log(params);
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
...fetchUtils.flattenObject(params.filter),
_sort: field,
_order: order,
_start: (page - 1) * perPage,
_end: page * perPage,
};
const url = `${getUrl(resource)}?${stringify(query)}`;
const paging = supportsPaging(resource);
return httpClient(url).then(
({ headers, json }) => {
var result = [];
// Implementierung von clientseitigem Paging & Filtering
var filtered = applyFilter(json, params.filter);
if (!paging) {
filtered=applyPagination(filtered, page, perPage);
}
else {
result = filtered;
}
return {
data: result,
total: json.length
};
}, ({ reason }) => {
console.log(reason);
}).catch((e)=>{
console.log(e);
});
}
I use this custom ponent in the edit form.
export const CSEJobList = ({ ...props }) => {
const form = useForm();
var formdata = form.getState().values;
console.log("CSEJobList");
if (formdata && formdata.status && formdata.status.id >= 2) {
var data = GetJobData({ 'filter': { type: 'abeitsschein_id_' + formdata.id } });
return data;
}
else {
return <div>Test</div>
}
};
CSEJobList.defaultProps = { label: 'Arbeitsschein', addLabel: true };
const GetJobData = (params) => {
let parms = { "pagination": { "page": 0, "perPage": 25 }, "sort": { "field": "id", "order": "ASC" }, "filter": {} };
const { data, loading, error } = useGetList('jobs', parms);
if (loading) { return <LinearProgress />; }
if (error) { return <p>ERROR</p>; }
return <p>{data}</p>;
};
This is just a basic test. Proper display of result data is not implemented yet since the call results in the mentioned error.
I read the documentation (https://marmelab./react-admin/Actions.html#specialized-hooks) about querying the API, fiddled around a lot, but I fail because of my limited understanding of promises.
Is there an easy fix?
Update:
I changed the dataProvider getList
function like so, return rejected promises as suggested:
getList: (resource, params) => {
console.log('DataProvider.GetList ');
console.log(resource);
console.log(params);
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
...fetchUtils.flattenObject(params.filter),
_sort: field,
_order: order,
_start: (page - 1) * perPage,
_end: page * perPage,
};
const url = `${getUrl(resource)}?${stringify(query)}`;
const paging = supportsPaging(resource);
return httpClient(url).then(
({ headers, json }) => {
var result = [];
// Implementierung von clientseitigem Paging & Filtering
var filtered = applyFilter(json, params.filter);
if (!paging) {
filtered=applyPagination(filtered, page, perPage);
}
else {
result = filtered;
}
return {
data: result,
total: json.length, // Erfordert nun keinen speziellen Header mehr, CSE-Connect kompatibel
};
}, ({ reason }) => {
return Promise.reject(reason);
}).catch((e)=>{
console.log(e);
return Promise.reject(e);
});
},
It had no effect. After some debugging I realized that in the GetJobData
function the line
if (loading) { return <LinearProgress />; }
causes the error. Exactly the same works in other parts of the code, so the suspect is not LinearProgress
. I actually have no Idea what causes the error. Debugging is hard to impossible because of timeouts.
This is the full stack trace:
useDataProvider.js:334 Uncaught Error: The dataProvider threw an error. It should return a rejected Promise instead.
at performQuery (useDataProvider.js:334)
at Proxy.<anonymous> (useDataProvider.js:163)
at JSON.stringify.query (useQueryWithStore.js:116)
at mitHookEffectList (react-dom.development.js:22030)
at mitPassiveHookEffects (react-dom.development.js:22064)
at HTMLUnknownElement.callCallback (react-dom.development.js:336)
at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
at invokeGuardedCallback (react-dom.development.js:440)
at flushPassiveEffectsImpl (react-dom.development.js:25392)
at unstable_runWithPriority (scheduler.development.js:697)
at runWithPriority$2 (react-dom.development.js:12149)
at flushPassiveEffects (react-dom.development.js:25361)
at performSyncWorkOnRoot (react-dom.development.js:24251)
at react-dom.development.js:12199
at unstable_runWithPriority (scheduler.development.js:697)
at runWithPriority$2 (react-dom.development.js:12149)
at flushSyncCallbackQueueImpl (react-dom.development.js:12194)
at flushSyncCallbackQueue (react-dom.development.js:12182)
at batchedUpdates$1 (react-dom.development.js:24392)
at Object.notify (Subscription.js:19)
at Subscription.notifyNestedSubs (Subscription.js:92)
at Subscription.handleChangeWrapper (Subscription.js:97)
at dispatch (redux.js:222)
at middleware.js:22
at redux-saga-core.esm.js:1410
at useDataProvider.js:300
Share
Improve this question
edited Feb 27, 2020 at 8:49
elsni
asked Feb 25, 2020 at 16:19
elsnielsni
2,0532 gold badges18 silver badges37 bronze badges
4
- what import do you use for LinearProgress? – François Zaninotto Commented Mar 3, 2020 at 23:37
- I use LinearProgress from react-admin – elsni Commented Mar 4, 2020 at 13:20
- There is no reason this ponent can fail... So I have no idea why your code doesn't work. – François Zaninotto Commented Mar 6, 2020 at 16:31
- LinearProgress works fine on other parts of the code, I have no Idea why this happens. – elsni Commented Mar 10, 2020 at 8:56
3 Answers
Reset to default 3Current implementation catchs the exception, if any, and say us that the exception should not be fired from the data provider, but the error should be returned as rejected promise:
Error: The dataProvider threw an error. It should return a rejected Promise instead.
Let's take a look to current code, it looks like this:
} catch (e) {
if (process.env.NODE_ENV !== 'production') {
console.error(e);
}
throw new Error(
'The dataProvider threw an error. It should return a rejected Promise instead.'
);
}
From this we can see that actual error is dumped to the console just before that as the mentioned error about rejected promise is fired.
Thus, to solve the problem, we need to scroll the console to the previously displayed error and fix it instead of the promise error, which is located below in the console and on the page itself. And if possible, also correct the provider to switch to the rejected promise. However, fixing the previous error will suffice.
if an error occurs, your dataProvider should return the following value:
import { HttpError } from 'react-admin'
...
return Promise.reject(new HttpError(message, status, body))
This is unrelated to OP's problem but I got this issue when I miss typed filters
to filter
:
<List filters={myPostFilters}> // this should be plural "filters"
// ...
</List>
If singular, somehow this will result in the same error as OP's.