I'm trying to use multiple dataproviders in a react-admin project but I have an error:
Warning: Missing translation for key: "dataProvider is not a function"
function.console.(anonymous function) @ index.js:1452
I have my App.js
like this:
import React from 'react';
import { render } from 'react-dom';
import { Admin, Resource } from 'react-admin';
import dataProviders from './service/dataproviders';
import UserList1, from './users1';
import UserList2, from './users2';
const App = () => (
render(
<Admin dataProvider={dataProviders}>
<Resource name="users1" list={UserList1} />
<Resource name="users2" list={UserList2} />
</Admin>,
document.getElementById('root'),
)
);
export default App;
And I have the dataproviders.js
file:
import simpleRestProvider from 'ra-data-simple-rest';
const dataProviders = [
{ dataProvider: simpleRestProvider('http://path.to.foo.api1'), resources: ['users1'] },
{ dataProvider: simpleRestProvider('http://path.to.foo.api2'), resources: ['users2'] },
];
export default (type, resource, params) => {
const dataProvider = dataProviders.find(dp => dp.resources.includes(resource));
return dataProvider(type, resource, params);
};
How it's the correct way?
I check this post:
Is it possible to have multiple dataProviders in react-admin?
You're not calling the dataProvider
you found, you're calling the mapping object from your array. You can fix it like this:
import simpleRestProvider from 'ra-data-simple-rest';
const dataProviders = [
{ dataProvider: simpleRestProvider('http://path.to.foo.api1'), resources: ['users1'] },
{ dataProvider: simpleRestProvider('http://path.to.foo.api2'), resources: ['users2'] },
];
export default (type, resource, params) => {
const dataProviderMapping = dataProviders.find(dp => dp.resources.includes(resource));
return dataProviderMapping.dataProvider(type, resource, params);
};
If you're wondering how to have multiple data sources as well as multiple dataProvider types i.e. rest, GraphQL e.t.c. The v3 docs state:
In react-admin v2, Data Providers used to be functions, not objects. React-admin v3 can detect a legacy Data Provider and wrap an object around it. So Data Providers developed for react-admin v2 still work with react-admin v3.
This means that the dataProvider property on the <Admin>
component can take:
This means that if you provide your DataProvider is a function, you will have to create an adapter and call the functions on your provider manually. Here is an example.
./dataProviders.js
import { gqlDataProvider, restGQLDataProvider, restProvider } from './buildDataProviders';
// The first assumption is that all resources are unique, thus we can use an object or a map instead of an array. Key = resource, value = DataProvider.
const dataProviders = new Map([
['users', restGQLDataProvider],
['users-local', restProvider],
['Invoice', gqlDataProvider],
['Debtor', gqlDataProvider],
['Status', gqlDataProvider]
]);
export default async (type, resource, params) => {
// Get the DataProvider from the map.
const dataProvider = await dataProviders.get(resource);
// The DataProvider object is wrapped in a function so we can pass in the parameters to get the result.
if (dataProvider instanceof Function) {
return dataProvider(type, resource, params);
}
};
./buildDataProvider.js
import { gql } from 'apollo-boost';
import buildGraphQLProvider from 'ra-data-graphql-simple';
import { gqlClient, restClient } from './apolloClients';
import simpleRestProvider from 'ra-data-simple-rest';
const LOCAL_REST_ENDPOINT = 'http://localhost:3001/api';
export RestProvider = simpleRestProvider(LOCAL_REST_ENDPOINT);
export const gqlDataProvider = buildGraphQLProvider({
client: gqlClient
});
// This is just an example of the getList provider, you'll have to write the rest.
export const restProvider = (type, resource, params) => {
const providerMap = new Map([
['GET_LIST', async () => {
return await RestProvider.getList(resource, params);
}]
])
export const restGQLDataProvider = (type, resource, params) => {
const providerMap = new Map([
['GET_LIST', async () => {
const query = gql`
query ${resource} {
${resource} @rest(type: "${resource}", path: "/${resource}") {
id
name
username
email
address
phone
website
company
}
}
`;
const result = await restClient.query({ query });
return { data: result.data[resource], total: result.data[resource].length };
}]
])
}
./apolloClients.js
import { ApolloClient, ApolloLink, InMemoryCache, HttpLink } from 'apollo-boost';
import { RestLink } from 'apollo-link-rest';
import auth from '../../auth';
const GRAPHQL_ENDPOINT = 'http://localhost:4000';
const REST_ENDPOINT = 'http://jsonplaceholder.typicode.com';
const httpLink = new HttpLink({ uri: GRAPHQL_ENDPOINT });
const authLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: {
'x-api-key': auth.aws_appsync_apiKey
}
});
return forward(operation);
});
export const restClient = new ApolloClient({
link: new RestLink({ uri: REST_ENDPOINT }),
cache: new InMemoryCache()
});
export const gqlClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With