How is the correct way to have multiple dataProviders in react-admin?

前端 未结 3 1761
忘掉有多难
忘掉有多难 2021-01-02 17:25

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 functio         


        
3条回答
  •  猫巷女王i
    2021-01-02 18:14

    I was faced with the same problem in the new version 3.1

    I decided to make a universal dataProvider

    dataProvider.js

    import {fetchUtils} from 'ra-core';
    import ApiEndpoints from '../config/ApiEndpoints';
    import {
    	restGetList,
    	restGetOne,
    	restGetMany,
    	restGetManyReference,
    	restUpdate,
    	restUpdateMany,
    	restCreate,
    	restDelete,
    	restDeleteMany,
    } from './rest/index';
    import {CONSTANTS} from '../constants';
    
    const httpClientTui = (url, options = {}) => {
    	if (!options.headers) {
    		// eslint-disable-next-line no-param-reassign
    		options.headers = new Headers({Accept: 'application/json'});
    	}
    	const token = localStorage.getItem(CONSTANTS.CMS_KEY.TOKEN);
    	options.headers.set('Authorization', `Bearer ${token}`);
    	return fetchUtils.fetchJson(url, options);
    };
    
    function selectApiEndpoint(resource = '') {
    	const result = {};
    	result.apiEndpoint = 'https://jsonplaceholder.typicode.com';	// default parameters
    	result.apiType = 'rest';
    	Object.keys(ApiEndpoints).forEach((key) => {
    		if (ApiEndpoints[key].url.includes(resource)) {
    			result.apiEndpoint = key.toString();
    			result.apiType = ApiEndpoints[key].type.toString();
    		}
    	});
    	return {
    		...result,
    	};
    }
    
    export default (apiUrl, httpClient = httpClientTui) => ({
    	getList: (resource, params) => {
    		const {apiEndpoint, apiType} = selectApiEndpoint(resource);
    		switch (apiType) {
    			case 'rest':
    				return restGetList(apiEndpoint, resource, params, httpClient);
    			default:
    				return restGetList(apiEndpoint, resource, params, httpClient);
    		}
    	},
    
    	getOne: (resource, params) => {
    		const {apiEndpoint, apiType} = selectApiEndpoint(resource);
    		switch (apiType) {
    			case 'rest':
    				return restGetOne(apiEndpoint, resource, params, httpClient);
    			default:
    				return restGetOne(apiEndpoint, resource, params, httpClient);
    		}
    	},
    
    	...
    });

    ApiEndpoints.js

    module.exports = {
    	'https://jsonplaceholder.typicode.com': {
    		type: 'rest',
    		url: [
    			'posts',
    			'comments',
    			'albums',
    			'photos',
    			'todos',
    			'users',
    		],
    	},
    };

    ./rest/index.js

    import {fetchUtils} from 'ra-core';
    import {stringify} from 'query-string';
    
    /**
     * From ra-data-json-server
     * https://github.com/marmelab/react-admin/blob/master/packages/ra-data-json-server/src/index.ts
     */
    
    /**
     * Get list
     * @param apiEndpoint {string} - domain
     * @param resource {string} - URI request
     * @param params {object} - params request
     * @param httpClient {function}
     * @returns {{data: object, total: number}}
     */
    export function restGetList(apiEndpoint, resource, params, httpClient) {
    	const {page, perPage} = params.pagination;
    	const {field, order} = params.sort;
    	const query = {
    		...fetchUtils.flattenObject(params.filter),
    		_sort: field,
    		_order: order,
    		_start: (page - 1) * perPage,
    		_end: page * perPage,
    	};
    	const url = `${apiEndpoint}/${resource}?${stringify(query)}`;
    
    	return httpClient(url).then(({headers, json}) => {
    		if (!headers.has('x-total-count')) {
    			throw new Error(
    				'not found x-total-count',
    			);
    		}
    		return {
    			data: json,
    			total: parseInt(
    				headers.get('x-total-count').split('/').pop()
    			),
    		};
    	});
    }
    
    /**
     * Get one record
     * @param apiEndpoint {string} - domain
     * @param resource {string} - URI request
     * @param params {object} - params request
     * @param httpClient {function}
     * @returns {{data: object}}
     */
    export function restGetOne(apiEndpoint, resource, params, httpClient) {
    	return httpClient(`${apiEndpoint}/${resource}/${params.id}`).then(({json}) => ({
    		data: json,
    	}));
    }
    
    ...

提交回复
热议问题