'GET_LIST' 的 dataProvider 可能是错误的
The dataProvider is probably wrong for 'GET_LIST'
我正在尝试将 react-admin 与 hasura 适配器一起使用。当我尝试使用 cruds 时,错误
The response to 'GET_LIST' must be like { data: ... }, but the received response does not have a 'data' key.
身份验证工作正常,但我看不到任何查询 "associado" 数据的请求。仅启动 AUTH_CHECK 请求,"associado" table 没有 graphql 请求。没有发出任何请求就抛出错误。
怎么了?
CRUD 关联文件:
import React from 'react';
import { List, Datagrid, TextField, Show, SimpleShowLayout, DateField } from 'react-admin';
export function AssociadoList(props) {
return (
<List {...props}>
<Datagrid>
<TextField source="nome" />
<DateField source="data_aniversario" />
{/*<ReferenceField label="Endereço" source="enderecoId" reference="enderecos">
<TextField source="bairro" />
<TextField source="bairro" />
</ReferenceField>*/}
</Datagrid>
</List>
)
};
export function AssociadoShow(props) {
return (
<Show {...props}>
<SimpleShowLayout>
<TextField source="nome" />
<DateField source="data_aniversario" />
</SimpleShowLayout>
</Show>
)
};
授权提供商:
import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK } from 'react-admin';
import graphql from './graphqlClient';
import Cookies from 'universal-cookie';
import { GraphQLClient } from 'graphql-request';
const cookies = new Cookies();
const LOGIN = `
mutation($username:String!, $password:String!){
login(username: $username, password: $password){
token
}
}
`;
const ME = `
query {
me {
username
}
}
`;
export default (type, params) => {
if (type === AUTH_LOGIN) {
const { username, password } = params;
return graphql.request(LOGIN, { username, password }).then(data => {
const token = data.login.token;
cookies.set("authToken", token, { path: "/", sameSite: "strict" });
});
}
if (type === AUTH_LOGOUT) {
cookies.remove("authToken", { path: "/", sameSite: "strict" });
return Promise.resolve();
}
if (type === AUTH_ERROR) {
const graphqlauth = new GraphQLClient(process.env.REACT_APP_HASURA_ENDPOINT, {
headers: {
authorization: 'Bearer ' + cookies.get('authToken'),
},
})
return graphqlauth.request(ME).then(data => { return (data.me.username) ? Promise.resolve() : Promise.reject(); }).catch(e => {
cookies.remove("authToken", { path: "/", sameSite: "strict" });
});
}
if (type === AUTH_CHECK) {
return cookies.get('authToken') ? Promise.resolve() : Promise.reject();
}
return Promise.resolve();
};
和 App.js;
import React from 'react';
import { Admin, Resource } from 'react-admin';
import Dashboard from './Dashboard';
import hasuraDataProvider from 'ra-data-hasura';
import authProvider from './authProvider';
import Cookies from 'universal-cookie';
import { AssociadoList, AssociadoShow } from "./Associado";
import portugueseMessages from 'ra-language-portuguese'
const dataProvider = function () {
const cookies = new Cookies();
const dataProvider = hasuraDataProvider(process.env.REACT_APP_HASURA_URL, { "content-type": "application/json", "Authorization": "Bearer " + cookies.get("AuthToken") });
return dataProvider;
}
const messages = {
'pt': portugueseMessages,
};
const i18nProvider = locale => messages[locale];
function App() {
return (
<Admin
dataProvider={dataProvider}
authProvider={authProvider}
dashboard={Dashboard}
locale="pt" i18nProvider={i18nProvider}
>
<Resource name="adear.associado" list={AssociadoList} options={{ label: 'Associado' }} show={AssociadoShow} />
</Admin>
);
}
export default App;
这是我的 package.json
{
"name": "dashboard",
"version": "0.1.0",
"private": true,
"dependencies": {
"graphql-request": "^1.8.2",
"ra-data-hasura": "^0.0.6",
"ra-language-portuguese": "^1.5.1",
"react": "^16.8.6",
"react-admin": "2.9.5",
"react-cookie": "^4.0.1",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
我的看法是您的自定义 dataProvider 有一个小问题。
您正在尝试增强 hasura 数据提供程序,但这样做会引入一个小错误。
import React from 'react';
import { Admin, Resource } from 'react-admin';
import Dashboard from './Dashboard';
import hasuraDataProvider from 'ra-data-hasura';
import authProvider from './authProvider';
import Cookies from 'universal-cookie';
import { AssociadoList, AssociadoShow } from "./Associado";
import portugueseMessages from 'ra-language-portuguese'
const dataProvider = function () {
const cookies = new Cookies();
// hasuraDataProvider is a factory, which returns a function
const dataProvider = hasuraDataProvider(process.env.REACT_APP_HASURA_URL, { "content-type": "application/json", "Authorization": "Bearer " + cookies.get("AuthToken") });
return dataProvider; // Here you are returning the real dataprovider
}
const messages = {
'pt': portugueseMessages,
};
const i18nProvider = locale => messages[locale];
function App() {
return (
<Admin
{/* dataProvider is a function which returns the hasura dataProvider, but React Admin expects to get your function results instead! */}
dataProvider={dataProvider}
authProvider={authProvider}
dashboard={Dashboard}
locale="pt" i18nProvider={i18nProvider}
>
<Resource name="adear.associado" list={AssociadoList} options={{ label: 'Associado' }} show={AssociadoShow} />
</Admin>
);
}
export default App;
恕我直言,修复就像在将 prop 传递给管理员时调用 dataProvider 函数一样简单。
- dataProvider={dataProvider}
+ dataProvider={dataProvider()}
我找到了答案。
要工作,您需要将授权令牌作为参数传递到 dataProvider 函数包装器中,并使用 react-cookie,您可以使用状态和 React Hooks 的所有功能。就像魔术一样:
import React from 'react';
import { Admin, Resource } from 'react-admin';
import Dashboard from './Dashboard';
import hasuraDataProvider from 'ra-data-hasura';
import authProvider from './authProvider';
import {useCookies} from "react-cookie";
import { AssociadoList, AssociadoShow } from "./Associado";
import portugueseMessages from 'ra-language-portuguese'
const dataProvider = function (authToken) {
const dataProvider = hasuraDataProvider("http://localhost:8080", { "content-type": "application/json", "Authorization": "Bearer " + authToken});
return dataProvider;
}
const messages = {
'pt': portugueseMessages,
};
const i18nProvider = locale => messages[locale];
function App() {
const [cookies] = useCookies(['authToken']);
return (
<Admin
dataProvider={dataProvider(cookies.authToken)}
authProvider={authProvider}
dashboard={Dashboard}
locale="pt" i18nProvider={i18nProvider}
>
<Resource name="adear.associado" list={AssociadoList} options={{ label: 'Associado' }} show={AssociadoShow} />
</Admin>
);
}
export default App;
我正在尝试将 react-admin 与 hasura 适配器一起使用。当我尝试使用 cruds 时,错误
The response to 'GET_LIST' must be like { data: ... }, but the received response does not have a 'data' key.
身份验证工作正常,但我看不到任何查询 "associado" 数据的请求。仅启动 AUTH_CHECK 请求,"associado" table 没有 graphql 请求。没有发出任何请求就抛出错误。 怎么了?
CRUD 关联文件:
import React from 'react';
import { List, Datagrid, TextField, Show, SimpleShowLayout, DateField } from 'react-admin';
export function AssociadoList(props) {
return (
<List {...props}>
<Datagrid>
<TextField source="nome" />
<DateField source="data_aniversario" />
{/*<ReferenceField label="Endereço" source="enderecoId" reference="enderecos">
<TextField source="bairro" />
<TextField source="bairro" />
</ReferenceField>*/}
</Datagrid>
</List>
)
};
export function AssociadoShow(props) {
return (
<Show {...props}>
<SimpleShowLayout>
<TextField source="nome" />
<DateField source="data_aniversario" />
</SimpleShowLayout>
</Show>
)
};
授权提供商:
import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK } from 'react-admin';
import graphql from './graphqlClient';
import Cookies from 'universal-cookie';
import { GraphQLClient } from 'graphql-request';
const cookies = new Cookies();
const LOGIN = `
mutation($username:String!, $password:String!){
login(username: $username, password: $password){
token
}
}
`;
const ME = `
query {
me {
username
}
}
`;
export default (type, params) => {
if (type === AUTH_LOGIN) {
const { username, password } = params;
return graphql.request(LOGIN, { username, password }).then(data => {
const token = data.login.token;
cookies.set("authToken", token, { path: "/", sameSite: "strict" });
});
}
if (type === AUTH_LOGOUT) {
cookies.remove("authToken", { path: "/", sameSite: "strict" });
return Promise.resolve();
}
if (type === AUTH_ERROR) {
const graphqlauth = new GraphQLClient(process.env.REACT_APP_HASURA_ENDPOINT, {
headers: {
authorization: 'Bearer ' + cookies.get('authToken'),
},
})
return graphqlauth.request(ME).then(data => { return (data.me.username) ? Promise.resolve() : Promise.reject(); }).catch(e => {
cookies.remove("authToken", { path: "/", sameSite: "strict" });
});
}
if (type === AUTH_CHECK) {
return cookies.get('authToken') ? Promise.resolve() : Promise.reject();
}
return Promise.resolve();
};
和 App.js;
import React from 'react';
import { Admin, Resource } from 'react-admin';
import Dashboard from './Dashboard';
import hasuraDataProvider from 'ra-data-hasura';
import authProvider from './authProvider';
import Cookies from 'universal-cookie';
import { AssociadoList, AssociadoShow } from "./Associado";
import portugueseMessages from 'ra-language-portuguese'
const dataProvider = function () {
const cookies = new Cookies();
const dataProvider = hasuraDataProvider(process.env.REACT_APP_HASURA_URL, { "content-type": "application/json", "Authorization": "Bearer " + cookies.get("AuthToken") });
return dataProvider;
}
const messages = {
'pt': portugueseMessages,
};
const i18nProvider = locale => messages[locale];
function App() {
return (
<Admin
dataProvider={dataProvider}
authProvider={authProvider}
dashboard={Dashboard}
locale="pt" i18nProvider={i18nProvider}
>
<Resource name="adear.associado" list={AssociadoList} options={{ label: 'Associado' }} show={AssociadoShow} />
</Admin>
);
}
export default App;
这是我的 package.json
{
"name": "dashboard",
"version": "0.1.0",
"private": true,
"dependencies": {
"graphql-request": "^1.8.2",
"ra-data-hasura": "^0.0.6",
"ra-language-portuguese": "^1.5.1",
"react": "^16.8.6",
"react-admin": "2.9.5",
"react-cookie": "^4.0.1",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
我的看法是您的自定义 dataProvider 有一个小问题。
您正在尝试增强 hasura 数据提供程序,但这样做会引入一个小错误。
import React from 'react';
import { Admin, Resource } from 'react-admin';
import Dashboard from './Dashboard';
import hasuraDataProvider from 'ra-data-hasura';
import authProvider from './authProvider';
import Cookies from 'universal-cookie';
import { AssociadoList, AssociadoShow } from "./Associado";
import portugueseMessages from 'ra-language-portuguese'
const dataProvider = function () {
const cookies = new Cookies();
// hasuraDataProvider is a factory, which returns a function
const dataProvider = hasuraDataProvider(process.env.REACT_APP_HASURA_URL, { "content-type": "application/json", "Authorization": "Bearer " + cookies.get("AuthToken") });
return dataProvider; // Here you are returning the real dataprovider
}
const messages = {
'pt': portugueseMessages,
};
const i18nProvider = locale => messages[locale];
function App() {
return (
<Admin
{/* dataProvider is a function which returns the hasura dataProvider, but React Admin expects to get your function results instead! */}
dataProvider={dataProvider}
authProvider={authProvider}
dashboard={Dashboard}
locale="pt" i18nProvider={i18nProvider}
>
<Resource name="adear.associado" list={AssociadoList} options={{ label: 'Associado' }} show={AssociadoShow} />
</Admin>
);
}
export default App;
恕我直言,修复就像在将 prop 传递给管理员时调用 dataProvider 函数一样简单。
- dataProvider={dataProvider}
+ dataProvider={dataProvider()}
我找到了答案。 要工作,您需要将授权令牌作为参数传递到 dataProvider 函数包装器中,并使用 react-cookie,您可以使用状态和 React Hooks 的所有功能。就像魔术一样:
import React from 'react';
import { Admin, Resource } from 'react-admin';
import Dashboard from './Dashboard';
import hasuraDataProvider from 'ra-data-hasura';
import authProvider from './authProvider';
import {useCookies} from "react-cookie";
import { AssociadoList, AssociadoShow } from "./Associado";
import portugueseMessages from 'ra-language-portuguese'
const dataProvider = function (authToken) {
const dataProvider = hasuraDataProvider("http://localhost:8080", { "content-type": "application/json", "Authorization": "Bearer " + authToken});
return dataProvider;
}
const messages = {
'pt': portugueseMessages,
};
const i18nProvider = locale => messages[locale];
function App() {
const [cookies] = useCookies(['authToken']);
return (
<Admin
dataProvider={dataProvider(cookies.authToken)}
authProvider={authProvider}
dashboard={Dashboard}
locale="pt" i18nProvider={i18nProvider}
>
<Resource name="adear.associado" list={AssociadoList} options={{ label: 'Associado' }} show={AssociadoShow} />
</Admin>
);
}
export default App;