Как проанализировать поле stringified JSON и отобразить результаты с помощью react-admin

#graphql #aws-amplify #react-admin

#graphql #aws-amplify #react-admin

Вопрос:

Я использую react-admin с Amplify. Один из моих типов graphql имеет поле AWSJSON, содержащее массив статусов для пакетного задания. Я бы хотел, чтобы этот массив отображался в datagrid, который пользователь может развернуть, чтобы увидеть результат каждого элемента в пакете.

Данные возвращаются из API в виде stringified JSON. Как я могу JSON.проанализировать данные, а затем передать их в arrayField для отображения с помощью Datagrid в моем списке / показать компоненты?

Содержимое поля выглядит следующим образом:

 [{"reference":"11134","status":"OK"},{"reference":"10278","status":"OK"}]
 

ОБНОВЛЕНИЕ: приведенный ниже ответ был дан после того, как я немного обновил модель данных, чтобы:

 [{"id": "somerandomuid", "clientReference":"11134","status":"OK"}]
 

Мой код выглядит так:

Схема:

   type JobTask
  @model
  @auth(
    rules: [
      { allow: owner }
      { allow: groups, groups: ["admins"] }
    ]
  ) {
  id: ID!
  results: AWSJSON
  status: String
  expiryDate: AWSTimestamp! @ttl
}
 

Показать компонент:

   export const TaskShow = (props) => {
    return (
    <Show title={props.header} {...props}>
      <SimpleShowLayout>
        <Datagrid expand={<ResultsPanel />}>
          <TextField
            key={cuid()}
            fullWidth={true}
            source="id"
            label="Batch Id"
          />
          <TextField
            key={cuid()}
            fullWidth={true}
            source="status"
            label="Status"
          />
        </Datagrid>
      </SimpleShowLayout>
    </Show>
    );
 

Компонент ResultsPanel:

 const ResultsPanel = (props) => {
  console.log(props)
  let resultsArray = JSON.parse(JSON.parse(props.record.results));
  console.log(resultsArray);
  return (
    <>
      {resultsArray.map((result) => {
        return (
          <ArrayField>
            <Datagrid>
              <TextField source="reference" />
              <TextField source="status" />
            </Datagrid>
          </ArrayField>
        );
      })}
    </>
  );
};
 

Но все, что я получаю, это:

Скриншот компонента react-admin

Комментарии:

1. Почему вы разбираете здесь дважды JSON.parse(JSON.parse(props.record.results)) ?

2. Это очень хороший вопрос. По какой-то причине строка имеет двойную строку. Если я разбираю его только один раз, тип по-прежнему является строкой, и map завершается ошибкой.

3. Это интересно. Является ли строковое значение '[{"reference":"11134","status":"OK"},{"reference":"10278","status":"OK"}]' ? Если разобрать это, я получу массив объектов на своей стороне. Кроме того, не могли бы вы поделиться этим TextField компонентом? Не уверен, является ли это частью библиотеки или нет, но я боюсь, что вы действительно отображаете только имя поля, а не значение.

4. это консольный журнал значений. Но на самом деле проблема не в этом. Проблема в том, как мне получить это проанализированное значение «в» компонент react admin datagrid?

5. Да, я разобрался с этим прошлой ночью. Проблема с исходным кодом в том, что вы правы, это строка. Я предполагаю, что он используется в качестве параметра функции внутри компонента. После долгой возни с list contextprovider я пришел к выводу, что это тоже не сработает. Подозреваю, что это связано с тем, что он должен находиться в компоненте списка, а не в компоненте показа.

Ответ №1:

Думал, что я опубликую свои выводы для всех, кто может столкнуться с этим.

Datagrid требует контекста, который для него предоставит компонент list, но поскольку это находится в компоненте show, я пытался вместо этого использовать Array для предоставления контекста.

Для компонента arrayField требуется исходный код, который должен быть строкой, которая точно соответствует полю / свойству в ответе API; это не может быть произвольный объект / массив. Однако свойство, которому соответствует строка, должно быть массивом, и нет способа сообщить компоненту обработать содержимое этого поля / свойства перед его использованием. Итак, Arrayfield отсутствует в качестве поставщика контекста.

Поскольку Array не работает с моей структурой данных, я подумал, что могу использовать RA listcontextprovider , который не очень хорошо документирован, но, похоже, позволяет вам создавать контекст, который может использоваться datagrid, насколько я могу судить. Но это всегда выдавало мне ошибку, когда я использовал его с правильными реквизитами (во всяком случае, насколько я мог судить — как я уже сказал, документация немного скудная).

В конце концов, я отказался от собственных компонентов RA как плохо подходящих для моего варианта использования и написал компонент пользовательского поля, который вместо этого делает то, что мне нужно (т. Е. Анализирует поле из записи и передает массив в datagrid для визуализации). Я использовал встроенную сетку данных MUI, которая работает как шарм:

 const ResultsPanel = (props) => {
  let resultsArray = JSON.parse(JSON.parse(props.record.results));
  let columns = [
    { field: "id", headerName: "Item Id", flex: 1 },
    { field: "clientReference", headerName: "Your Reference", flex: 1 },
    { field: "status", headerName: "Import Status", flex: 1 },
  ];
  return (
    <div style={{ height: 400, width: "100%" }}>
      <DataGrid columns={columns} rows={resultsArray} />
    </div>
  );
};