0

I have just been playing around with the react-admin framework and tried to implement a custom dataprovider. I read the documentation on how to do this and eventually used the example as a starting point at: https://marmelab.com/react-admin/DataProviders.html#example-implementation

I received the following error in the console:

Warning: Failed prop type: Invalid prop dataProvider of type object > supplied to CoreAdmin, expected function. in CoreAdmin (created by withContext(CoreAdmin)) in withContext(CoreAdmin) (at App.js:16) in App (at index.js:7)

This is my App.js

import React from 'react';
import { Admin, Resource } from 'react-admin';
import { AssetList } from './assets.js';
import OssApiProvider from './DataProviders/OssApiProvider.js';
import { GET_LIST } from 'react-admin';

const dataProvider = OssApiProvider(
    GET_LIST,
    'asset',
    {
        pagination: {offset: 0, limit: 10},
        sort: {field: 'id', order: 'asc'}
    }
);
const App = () => (
    <Admin dataProvider={dataProvider}>
        <Resource name="asset" list={AssetList} />
    </Admin>
);

export default App;

And this is my dataprovider: DataProviders/OssApiProvider.js

import { stringify } from 'query-string';
import {
    GET_LIST,
    GET_ONE,
    CREATE,
    UPDATE,
    UPDATE_MANY,
    DELETE,
    DELETE_MANY,
    GET_MANY,
    GET_MANY_REFERENCE,
} from 'react-admin';

const apiUrl = '';

/**
 * Maps react-admin queries to OSS REST API
 *
 * @param {string} type Request type, e.g GET_LIST
 * @param {string} resource Resource name, e.g. "posts"
 * @param {Object} payload Request parameters. Depends on the request type
 * @returns {Promise} the Promise for a data response
 */
export default (type, resource, params) => {
    let url = '';
    const options = { 
        headers : new Headers({
            Accept: 'application/json',
        }),
    };
    switch (type) {
        case GET_LIST: {
            const { offset, limit } = params.pagination;
            const { field, order } = params.sort;
            const query = {
                sort: field,
                order: order.toLowerCase(),
                offset: JSON.stringify(offset),
                limit: JSON.stringify(limit),
                filter: JSON.stringify(params.filter),
            };
            url = `${apiUrl}/${resource}?${stringify(query)}`;
            break;
        }
        case GET_ONE:
            url = `${apiUrl}/${resource}/${params.id}`;
            break;
        case CREATE:
            url = `${apiUrl}/${resource}`;
            options.method = 'POST';
            options.body = JSON.stringify(params.data);
            break;
        case UPDATE:
            url = `${apiUrl}/${resource}/${params.id}`;
            options.method = 'PUT';
            options.body = JSON.stringify(params.data);
            break;
        case UPDATE_MANY:
            const query = {
                filter: JSON.stringify({ id: params.ids }),
            };
            url = `${apiUrl}/${resource}?${stringify(query)}`;
            options.method = 'PATCH';
            options.body = JSON.stringify(params.data);
            break;
        case DELETE:
            url = `${apiUrl}/${resource}/${params.id}`;
            options.method = 'DELETE';
            break;
        case DELETE_MANY:
            // const query = {
            //     filter: JSON.stringify({ id: params.ids }),
            // };
            url = `${apiUrl}/${resource}?${stringify(query)}`;
            options.method = 'DELETE';
            break;
        case GET_MANY: {
            const query = {
                filter: JSON.stringify({ id: params.ids }),
            };
            url = `${apiUrl}/${resource}?${stringify(query)}`;
            break;
        }
        case GET_MANY_REFERENCE: {
            const { page, perPage } = params.pagination;
            const { field, order } = params.sort;
            const query = {
                sort: JSON.stringify([field, order]),
                range: JSON.stringify([
                    (page - 1) * perPage,
                    page * perPage - 1,
                ]),
                filter: JSON.stringify({
                    ...params.filter,
                    [params.target]: params.id,
                }),
            };
            url = `${apiUrl}/${resource}?${stringify(query)}`;
            break;
        }
        default:
            throw new Error(`Unsupported Data Provider request type ${type}`);
    }

    return fetch(url, options)
        .then(res => {
            return res.json();
        })
        .then(json => {
            console.log(json)
            switch (type) {
                case GET_LIST:
                case GET_MANY_REFERENCE:
                    var response = {
                        data: json._embedded[Object.keys(json._embedded)[0]],
                        total: parseInt(json.total, 10),
                    };
                    console.log(response);
                    return response;
                case CREATE:
                    return { data: { ...params.data, id: json.id } };
                default:
                    return { data: json };
            }
        }
    );
};

Anyone know where to look or better yet fix it because I just run out of ideas?

4

1 回答 1

1

Your OssApiProvider seems fine!

The problem lies in App.js: when you import OssApiProvider it is your data provider. You don't have to call the function, you can pass it as is.

For example:

const App = () => (
    <Admin dataProvider={OssApiProvider}>
        <Resource name="asset" list={AssetList} />
    </Admin>
);
于 2018-07-19T15:33:23.053 回答