user14709104
user14709104

Reputation:

React-Admin custom api call

I'm trying to use react-admin for my admin dashboard(React+NodeJS) The api that I'm trying to use is

http://localhost:8000/api/v1/countries

This is the json response:

{
  "error": "false",
  "data": [
    {
      "country_name": "Afghanistan",
      "country_capital": "Kabul",
      "country_area": "652230",
      "country_currency": "Afghani افغانی",
      "continent": "Asia"
    },
    {
      "country_name": "Bhutan",
      "country_capital": "Thimphu",
      "country_area": "38,394",
      "country_currency": "Ngultrum (BTN)",
      "continent": "Asia"
    },
    .........
  ]
}

The idea is to implement basic CRUD operations in Admin Dashboard

this is my Dashboard.js component

import * as React from "react";
import { Admin, Resource } from 'react-admin';
import simpleRestProvider from 'ra-data-simple-rest';

import {CountryList} from '../../Components/Country/Country';


const Dashboard = () => (
    <Admin title="My Custom Admin" dataProvider={simpleRestProvider('http://localhost:8000/api/v1/countries')}>
        <Resource name="Countries" list={CountryList} />
    </Admin>
);

export default Dashboard

My country.js is as follows

import * as React from "react";
import { List, Datagrid, TextField, EmailField } from 'react-admin';

export const CountryList = props => (
    <List {...props}>
        <Datagrid rowClick="edit">
            <TextField source="country_name" />
            <TextField source="country_name" />
            <TextField source="country_area" />
            <TextField source="country_currency" />
            <TextField source="continent" />
        </Datagrid>
    </List>
);

And Finally the api is as follows:

app.get("/api/v1/countries", async (request, response) => {
            try{
                const countries = await database.query(
                    `SELECT * FROM COUNTRIES`,
                );
                response.status(200);
                if(countries.length > 0)
                {
                    response.json({
                        error: "false",
                        data: countries
                    });
                }
                else{
                    response.json({
                        error: "true"
                    })
                }   
            }
            catch (e) {
                response.status(500);
                response.json(e);
            }
        });
}

In index.js

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json());
app.use(cors());

This is the error that I'm getting:

The Content-Range header is missing in the HTTP Response. The simple REST data provider expects 
responses for lists of resources to contain this header with the total number of results to build the 
pagination. If you are using CORS, did you declare Content-Range in the Access-Control-Expose-Headers 
header?

Image: enter image description here

So, what am I doing wrong here? Do I need to re-write my api or does it have something to do with the data providers?

Upvotes: 1

Views: 2884

Answers (2)

Biprodas
Biprodas

Reputation: 31

  1. Add cors middleware in your backend application:
app.use(cors({
  exposedHeaders: ['Content-Range']
 }));
  1. Include Content-Range in the response header:
const countries = [{id:1,name:"Bangladesh"},{id:2,name:"India"}];
return res
  .status(200)
  .set("Content-Range", countries.length)
  .json(countries);
  1. In your react app
    <Admin 
      dataProvider={simpleRestProvider('http://localhost:8000/api/v1')}
    >
      <Resource 
        name="countries" 
        options={{ label: 'Countries' }}
        list={CountryList}
      />
    </Admin>

and everything is ok.

Upvotes: 3

MaxAlex
MaxAlex

Reputation: 3319

The server response must contain the header: "Content-Range" indicating the total number of items in the collection: https://marmelab.com/react-admin/DataProviders.html#usage

Upvotes: 2

Related Questions