首页 > 解决方案 > React-admin:dataProvider 抛出错误。它应该返回一个被拒绝的 Promise。- 尝试在 pg 数据库中设置参照完整性

问题描述

我正在将 react-admin 设置为汉堡餐厅的仪表板。这是我的我的 github存储库

如果缺少任何必需的故障排除信息,我深表歉意。我有点超出我的深度,但我正在尝试。

我创建了两个表(如果计算联系人,三个表)来存储菜单和菜单类别。我试图设置参照完整性。执行此操作后(并使用新的 seed.sql 文件重建项目),单击左侧的“menucategories”后,我立即开始获得以下信息:

在此处输入图像描述

Error: The dataProvider threw an error. It should return a rejected Promise instead.

   in List (at MenuCategory.js:5)
   in CatData (created by WithPermissions)
   in WithPermissions (created by Context.Consumer)
   in Route (created by ResourceRoutes)
   in Switch (created by ResourceRoutes)
   in ResourceRoutes (created by Resource)
   in Resource (at App.js:41)
   in Route (created by RoutesWithLayout)
   in Switch (created by RoutesWithLayout)
   in RoutesWithLayout (created by Context.Consumer)
   in div (created by Layout)
   in main (created by Layout)
   in div (created by Layout)
   in div (created by Layout)
   in Layout (created by WithStyles(Layout))
   in WithStyles(Layout) (created by Context.Consumer)
   in withRouter(WithStyles(Layout)) (created by ConnectFunction)
   in ConnectFunction (created by LayoutWithTheme)
   in ThemeProvider (created by LayoutWithTheme)
   in LayoutWithTheme (created by Context.Consumer)
   in Route (created by CoreAdminRouter)
   in Switch (created by CoreAdminRouter)
   in div (created by CoreAdminRouter)
   in CoreAdminRouter (created by Context.Consumer)
   in Route (created by CoreAdminUI)
   in Switch (created by CoreAdminUI)
   in CoreAdminUI (created by AdminUI)
   in AdminUI (created by Admin)
   in Router (created by ConnectedRouter)
   in ConnectedRouter (created by Context.Consumer)
   in ConnectedRouterWithContext (created by ConnectFunction)
   in ConnectFunction (created by CoreAdminContext)
   in TranslationProvider (created by CoreAdminContext)
   in Provider (created by CoreAdminContext)
   in CoreAdminContext (created by AdminContext)
   in AdminContext (created by Admin)
   in Admin (at App.js:25)
   in ReactAdminWrapper (at App.js:65)
   in ApolloProvider (at App.js:64)
   in App (at src/index.js:7)

控制台的第一批错误信息是这样的:

index.js:1 Warning: Failed prop type: The prop `children` is marked as required in `ForwardRef(Link)`, but its value is `null`.
   in ForwardRef(Link) (created by WithStyles(ForwardRef(Link)))
   in WithStyles(ForwardRef(Link))
   in Unknown
   in Unknown (at Contacts.js:13)
   in td (created by ForwardRef(TableCell))
   in ForwardRef(TableCell) (created by WithStyles(ForwardRef(TableCell)))
   in WithStyles(ForwardRef(TableCell)) (created by DatagridCell)
   in DatagridCell (created by DatagridRow)
   in tr (created by ForwardRef(TableRow))
   in ForwardRef(TableRow) (created by WithStyles(ForwardRef(TableRow)))
   in WithStyles(ForwardRef(TableRow)) (created by DatagridRow)
   in DatagridRow
   in tbody (created by ForwardRef(TableBody))
   in ForwardRef(TableBody) (created by WithStyles(ForwardRef(TableBody)))
   in WithStyles(ForwardRef(TableBody)) (created by DatagridBody)
   in DatagridBody (created by Datagrid)
   in table (created by ForwardRef(Table))
   in ForwardRef(Table) (created by WithStyles(ForwardRef(Table)))
   in WithStyles(ForwardRef(Table)) (created by Datagrid)
   in Datagrid (at Contacts.js:6)
   in div (created by ForwardRef(Paper))
   in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
   in WithStyles(ForwardRef(Paper)) (created by ForwardRef(Card))
   in ForwardRef(Card) (created by WithStyles(ForwardRef(Card)))
   in WithStyles(ForwardRef(Card)) (created by ListView)
   in div (created by ListView)
   in div (created by ListView)
   in ListView (created by List)
   in List (at Contacts.js:5)
   in ContactList (created by WithPermissions)
   in WithPermissions (created by Context.Consumer)
   in Route (created by ResourceRoutes)
   in Switch (created by ResourceRoutes)
   in ResourceRoutes (created by Resource)
   in Resource (at App.js:26)
   in Route (created by RoutesWithLayout)
   in Switch (created by RoutesWithLayout)
   in RoutesWithLayout (created by Context.Consumer)
   in div (created by Layout)
   in main (created by Layout)
   in div (created by Layout)
   in div (created by Layout)
   in Layout (created by WithStyles(Layout))
   in WithStyles(Layout) (created by Context.Consumer)
   in withRouter(WithStyles(Layout)) (created by ConnectFunction)
   in ConnectFunction (created by LayoutWithTheme)
   in ThemeProvider (created by LayoutWithTheme)
   in LayoutWithTheme (created by Context.Consumer)
   in Route (created by CoreAdminRouter)
   in Switch (created by CoreAdminRouter)
   in div (created by CoreAdminRouter)
   in CoreAdminRouter (created by Context.Consumer)
   in Route (created by CoreAdminUI)
   in Switch (created by CoreAdminUI)
   in CoreAdminUI (created by AdminUI)
   in AdminUI (created by Admin)
   in Router (created by ConnectedRouter)
   in ConnectedRouter (created by Context.Consumer)
   in ConnectedRouterWithContext (created by ConnectFunction)
   in ConnectFunction (created by CoreAdminContext)
   in TranslationProvider (created by CoreAdminContext)
   in Provider (created by CoreAdminContext)
   in CoreAdminContext (created by AdminContext)
   in AdminContext (created by Admin)
   in Admin (at App.js:25)
   in ReactAdminWrapper (at App.js:65)
   in ApolloProvider (at App.js:64)
   in App (at src/index.js:7)

在学习如何设置参照完整性时,我指的是以下教程。

请注意,repo 中的 seed.sql 文件尚未更新为我正在使用的版本(在我的机器上),如下所示:


CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public;

DROP TABLE IF EXISTS public.contacts CASCADE;

CREATE TABLE public.contacts (
    id             UUID PRIMARY KEY DEFAULT uuid_generate_v4() NOT NULL,
    email          VARCHAR(255) NOT NULL,
    firstname      VARCHAR(255),
    lastname       VARCHAR(255),
    website        VARCHAR(255),
    streetaddress  VARCHAR(255),
    phone          VARCHAR(255),
    companyname    VARCHAR(255),
    created_at     TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX contacts_email_index ON public.contacts (email);


DROP TABLE IF EXISTS public.menu CASCADE;

CREATE TABLE public.menu (
    id             SERIAL PRIMARY KEY,
    title          VARCHAR(255) NOT NULL,
    category_id    INT NOT NULL CONSTRAINT menu__ref_p REFERENCES menucategories,
    price          NUMERIC(8, 2),
    desc1          VARCHAR(255),
    isenabled      BOOLEAN NOT NULL DEFAULT TRUE,   
    created_at     TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);


DROP TABLE IF EXISTS public.menucategories CASCADE;

CREATE TABLE public.menucategories (
    category_id    SERIAL PRIMARY KEY,
    catname        VARCHAR(255) NOT NULL,
    created_at     TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);



SET client_min_messages = INFO;

测试数据通过fixtures.sql文件预填充到数据库中


INSERT INTO public.contacts
   (
       id,
       email,
       firstname,
       lastname
   )
   SELECT
       ('1de9c987-08ab-32fe-e218-89c124cd' || to_char(seqnum, 'FM0000'))::uuid,
       'firstname' || to_char(seqnum, 'FM0000') || '@example.com',
       'firstname' || to_char(seqnum, 'FM0000'),
       'lastname' || to_char(seqnum, 'FM0000')
   FROM 
       GENERATE_SERIES(1, 2) seqnum;

TRUNCATE public.menu CASCADE;

INSERT INTO public.menucategories
   (
       catname
   )
   SELECT
       ('category' || to_char(seqnum, 'FM0000'))
       
   FROM 
       GENERATE_SERIES(1, 3) seqnum;         

这是我的 App.js 文件中的代码:


import React, { useEffect, useState } from 'react'
import { ApolloProvider } from '@apollo/react-hooks';
import { Admin, Resource } from 'react-admin'
import { useApolloClient } from '@apollo/react-hooks'
import pgDataProvider from 'ra-postgraphile'
import { ContactList, ContactEdit, ContactCreate } from './Contacts'
import { MenuData, MenuEdit, CreateMenuItem } from './Menu'
import { CatData, CatEdit, CreateCatItem } from './MenuCategory'
import ApolloClient from './Apollo';
/* import { HttpError } from 'react-admin'; */

const ReactAdminWrapper = () => {
    const [dataProvider, setDataProvider] = useState(null);
    const client = useApolloClient();

    useEffect(() => {
        (async () => {
            const dataProvider = await pgDataProvider(client);
            setDataProvider(() => dataProvider);
        })()
    }, [client]);

    return (
        dataProvider && (
            <Admin dataProvider={dataProvider}>
                <Resource
                    name="contacts"
                    list={ContactList}
                    edit={ContactEdit}
                    create={ContactCreate}
                />

                <Resource 
                     name="menu"
                     list={MenuData}
                     edit={MenuEdit}
                     create={CreateMenuItem} 
                 
                />

              <Resource 
                     name="menucategories"
                     list={CatData}
                     edit={CatEdit}
                     create={CreateCatItem} 
                 
                />




            </Admin>
        )

        

     

    );
}

const App = () => {
    return (
        <ApolloProvider client={ApolloClient}>
            <ReactAdminWrapper />
        </ApolloProvider>
    );
}

export default App;

我正在使用 AutocompleteInput 来(硬编码)预填充值,但我需要将其更改为 ReferenceField 或ReferenceInput之类的东西以从数据库中提取类别。我只是不是 100% 确定如何做到这一点,因为我是 react-admin 的新手。任何建议将不胜感激。

我的 Menu.js 文件如下:

import React from 'react';
import { List, Datagrid, Edit, Create, SimpleForm, TextField, EditButton, TextInput, BooleanInput, BooleanField } from 'react-admin';
import { AutocompleteInput } from 'react-admin';

export const MenuData = (props) => (
    <List {...props}>
        <Datagrid>
            
            <TextField source="title" />
            <TextField source="category_id" />
            <TextField source="price" />
            <TextField source="desc1" />
            {/* <TextField source="image" /> */}
            <BooleanField label="enabled" source="isenabled" />
            
            <EditButton basePath="/menu" />
        </Datagrid>
    </List>
);

const MenuTitle = ({ record }) => {
    return <span>Menu {record ? `"${record.title}"` : ''}</span>;
};

export const MenuEdit = (props) => (
    <Edit title={<MenuTitle />} {...props}>
        <SimpleForm>
            <TextInput disabled source="id" />
            
            <TextInput source="title" />

{/* //These are currently hardcoded see: https://marmelab.com/react-admin/Inputs.html
//We want to grab the values from the database instead */}

    <AutocompleteInput source="category_id" choices={[
    { id: '1', name: 'category0001' },
    { id: '2', name: 'category0002' },
    { id: '3', name: 'category0003' },
   
]} />
            {/* <TextInput source="category_id" /> */}
            <TextInput source="price" />
            <TextInput disabledsource="image" />
            <TextInput source="desc1" />
            <BooleanInput label="Enabled" source="isenabled" />
            
        </SimpleForm>
    </Edit>
);

export const CreateMenuItem = (props) => (
    <Create title="Add a Menu Item" {...props}>
        <SimpleForm>
        <TextInput disabled source="id" />
            
            <TextInput source="title" />
           
            <AutocompleteInput source="category_id" choices={[
    { id: '1', name: 'category0001' },
    { id: '2', name: 'category0002' },
    { id: '3', name: 'category0003' },
   
]} />

            {/* <TextInput source="category_id" /> */}
            <TextInput source="price" />
          {/*   <TextInput disabledsource="image" /> */}
            <TextInput source="desc1" />
        </SimpleForm>
    </Create>
);

import React from 'react';
import { List, Datagrid, Edit, Create, SimpleForm, TextField, EditButton, TextInput } from 'react-admin';
//ReferenceField
export const CatData = (props) => (
    <List {...props}>
        <Datagrid>
            
            

            <TextField source="catname" />
         
       
            
            <EditButton basePath="/menucategories" />
        </Datagrid>
    </List>
);

const CatTitle = ({ record }) => {
    return <span>Category {record ? `"${record.title}"` : ''}</span>;
};

export const CatEdit = (props) => (
    <Edit title={<CatTitle />} {...props}>
        <SimpleForm>
            <TextInput disabled source="id" />
            <TextInput label="Category name" source="catname" />
         </SimpleForm>
    </Edit>
);

export const CreateCatItem = (props) => (
    <Create title="Add a Category" {...props}>
        <SimpleForm>
        <TextInput disabled source="id" />
        <TextInput label="Category name"  source="catname" />
          </SimpleForm>
    </Create>
);

任何帮助或帮助将不胜感激。

标签: postgresqlgraphqlreact-adminpostgraphile

解决方案


推荐阅读