Search code examples
react-admin

How to access nested values from record in React-Admin


I'm trying to access nested values in a REST API array within the LIST VIEW of a React-Admin project. In short I'm trying to do something like "Array.item" when passing it to a component that renders it.

I've got my data populating like so:

Each messages array looks like this, so here's one of them:

for (let i = 0; i < 13; i++) {
      data.messagesDirect.push({
         id: i,
         read: faker.random.boolean(),
         date: faker.date.past(),
         subject:
            faker.name.jobDescriptor() +
            ' ' +
            faker.name.jobArea() +
            ' ' +
            faker.name.jobType(),
         content: faker.lorem.paragraph(),

         email:
            faker.internet.email() +
            ' - ' +
            faker.name.firstName() +
            ' ' +
            faker.name.lastName()
      });
   }

And then I put them in one array in the end.

data.messages.push({
      id: 0,
      inbox: data.messagesInbox,
      outbox: data.messagesOutbox,
      direct: data.messagesDirect
   });

data.messagesInbox,outbox and direct are generic arrays, they contain the same type of data.

I'm trying to access each array individually, and pass that information to be rendered by a component made to render these arrays.

export const MessagesList = props => (
   <FullWidthTabs>
      <List actions={<InboxListActions />} {...props}>
         <MessagesGrid data="messages.inbox" />
      </List>

      <List actions={<OutboxListActions />} {...props}>
         <MessagesGrid data="messages.outbox" />
      </List>

      <List actions={<DirectListActions />} {...props}>
         <MessagesGrid data="messages.direct" />
      </List>
   </FullWidthTabs>
);

No matter what it keeps passing the context of the array as if it's only at the top level, it's never passing the exact array object I'm referencing with the "."

I am doing this wrong, and I need understanding and guidance on how to do this right.

Messages grid just expects an array to iterate through and create UI for each item.

const MessagesGrid = ({ data, basePath, resource }) =>
   console.log(data) || (
      <div style={{ margin: '1em' }}>
         {data.map(id => (
            <Card key={id} style={cardStyle}>
               <ReadField record={data[id]} source="confirmed" />
               <CardHeader
                  title={<TextField record={data[id]} source="subject" />}
                  subheader={<DateField record={data[id]} source="date" />}
               />

               <CardContent>
                  <TextField record={data[id]} source="content" />
               </CardContent>

...


Solution

  • Figured it out, doing it like this, by wrapping them in Datagrids and using ArrayField it was able to step into each array:

    export const MessagesList = (props, resource) => (
       <FullWidthTabs>
          <List actions={<InboxListActions />} {...props}>
             <Datagrid>
                <ArrayField source="inbox">
                   <MessagesGrid />
                </ArrayField>
             </Datagrid>
          </List>
    
          <List actions={<OutboxListActions />} {...props}>
             <Datagrid>
                <ArrayField source="outbox">
                   <MessagesGrid />
                </ArrayField>
             </Datagrid>
          </List>
    
          <List actions={<DirectListActions />} {...props}>
             <Datagrid>
                <ArrayField source="direct">
                   <MessagesGrid />
                </ArrayField>
             </Datagrid>
          </List>
       </FullWidthTabs>
    );