Is your feature request related to a problem? Please describe.
It should be possible to pass filter params to the data provider when it is called by Edit component. My API accepts an embedded field, a dictionary that indicates which field should be embedded to the response (ej: for embedded={"category":1}, the API responds with the category object instead of the category id that is actually stored in de DB, referencing an object of the category collection).
Describe the solution you'd like
Let Edit component to accept filterDefaultValues, as List does.
Any reason you can't do it in your dataProvider ?
I'm currently facing the same issue. I want to be able to pass some parameters to the dataProvider from edit and create so I can avoid adding a lot of logic in the dataProvider to handle special cases for each entity.
This is how our API works:
GET api/authors:
{
"data": [
{
"id": 123,
"name": "Joachim"
},
...
],
...
}
GET api/authors?with=books:
{
"data": [
{
"id": 123,
"name": "Joachim",
"books": [
{
"id": 321,
"title": "React-admin for dummies"
},
...
]
},
...
],
...
}
For example. I want to fetch an Author with Books relation, and show the books in ReferenceArrayInput. To do that, I need a way to change the url from api/authors to api/authors?with=books which would be easy if we could pass a filter.
```javascript
const AuthorEdit = props => (
source="books.id"
reference="books"
>
);
Any reason you can't do it in your dataProvider ?
@djhi, could you please provide an example code to achieve what @Nohac proposed?
Nope because it's not supported
I don't understand what the filter would apply to. the Edit view uses the dataProvider.getOne() method, which usually translates to a search by id that doesn't accept any filter. If you need to filter a list of related records, then you can use the filter prop of the <ReferenceArrayInput> and <ReferenceArrayField>.
What you describe is not a filter but an embed. And react-admin does not support asking for specific shapes of resources for specific pages, because the resources are shared between pages (and because this type of optimization isn't needed in react-admin that does deduplication and aggregation of requests on its own).
And react-admin does not support asking for specific shapes of resources for specific pages
Ok, got it. But could it be possible to pass custom attributes to data provider from Edit component?
I understand that you need to add specific parameters to call your API for some specific resources. The right place to do that in react-admin is the data Provider.
I understand that you need to add specific parameters to call your API for some specific resources. The right place to do that in react-admin is the data Provider.
As an example, my API does not provide an attribute field id which is needed for react-admin to display the Edit with getOne. I would like to provide an custom parameter to the dataProvider from the Edit of my clients resource, letting the dataProvider know that the returned data need to be changed from UserId to id. This is different for each resource, so I cant hardcode it into the data-provider.
So is there any way to send params to the data-provider based on the resource or just as a parameter from the Edit component?
The goal of the data provider is to be the proxy between your API and React-Admin. React-Admin only speaks one language based on the ids. But if your API has several standards (for example one for the users, another one for the posts and the third one for the comments), you have to adapt your data provider accordingly.
Fortunately, you can build a custom data provider which has different behaviour depending on the resource. For example, the verb getOne accepts the resource and the params as a parameter.
So it's possible to do something like:
// dataProvider.js
{
getOne: (resource, params) => {
if (resource === 'users') {
return fetch(`my-api.com/users/${params.id}`)
.then(res => res.json())
.then(({ userId, ...data }) => ({ id: userId, ...data })); // Adapt the response to speak the React-Admin lang
}
if (resource === 'posts') {
return; /** ... */
}
if (resource === 'comments') {
return; /** ... */
}
};
}