Search code examples
react-adminapi-platform.com

Access Property of a Nested Record


I'm using React-Admin 3.5.0 with api-platform/admin 2.1.1.

I have a custom list for one of my resources.
The resource has a title and an author. The author has several properties, one of which is username.

Following the documentation, I tried to display the username of the author in my list like this:

export const MyList = (props) =>
    <List {...props}>
        <Datagrid>
            <TextField source="title" />
            <TextField source="author.username" />
        </Datagrid>
    </List>

This does not work. The field for author.username is empty.

I investigated a bit and found that the record only contains the ID of the author:

record:
    ...
    title: "abcde"
    author: "/users/1"

The response from the server however does contain the username property:

0: {
    ...,
    "title": "abcde",
    "author": {
        "@id": "/users/1",
        "username": "Test"
    }
},
...

Is there any nice way to make it work?


Solution

  • Found this on api-platform admin source code:

    Replace embedded objects by their IRIs, and store the object itself in the cache to reuse without issuing new HTTP requests.

    And right below:

    document[key] = document[key]['@id'];
    

    https://github.com/api-platform/admin/blob/ba0630083f28eaa8806bc1da4613677924604a52/src/hydra/dataProvider.js#L75

    This behavior came from this pull request:

    https://github.com/api-platform/admin/pull/96

    To display author fields, you will need to use a ReferenceField for each one of them:

    export const MyList = (props) =>
        <List {...props}>
            <Datagrid>
                <TextField source="title" />
                <ReferenceField source="author" reference="users">
                    <TextField source="username"/>
                </ReferenceField>
    
                <ReferenceField source="author" reference="users" link={false}>
                    <TextField source="email"/>
                </ReferenceField>
            </Datagrid>
        </List>
    

    Doing it will make the author fields link to the author page. You can disable this passing link={false} on the ReferenceField, like on the second author field above

    React admin will pack all those author reference requests into a single one, so even if api-platform data provider woun't do it's cache promise, you will endup with only one http request.

    Note: You must add a <Resource> for the reference resource - react-admin needs it to fetch the reference data. You can omit the list prop in this reference if you want to hide it in the sidebar menu.