简单的休息数据提供者将不接受Odata数据

时间:2018-12-05 18:33:33

标签: odata react-admin

因此我正在使用的API使用的是ODATA(https://www.odata.org/)。结果就是返回时的样子

```

{"@odata.context":"http://localhost:5001/api/$metadata#apemp",
"value":[
{"EmpID":1,
"Abbr":"Admin",
"BadgeNo":null,
"ColorRef":0,
"ContactMethodID":null,
"DateHired":"2018-05-25T16:42:57-05:00"}

]```

我们的数据提供商看起来像这样

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

...
   const convertHTTPResponse = (response, type, resource, params) => {
      const { headers, json } = response;
      switch (type) {
         case GET_LIST:
            return { data: json };
         case GET_MANY_REFERENCE:
            if (!headers.has('content-range')) {
               throw new Error(
                  '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?'
               );
            }
            return {
               data: json,
               total: parseInt(
                  headers
                     .get('content-range')
                     .split('/')
                     .pop(),
                  10
               )
            };
         case CREATE:
            return { data: { ...params.data, id: json.id } };
         default:
            return { data: json };
      }
   };

   return (type, resource, params) => {
      // simple-rest doesn't handle filters on UPDATE route, so we fallback to calling UPDATE n times instead
      if (type === UPDATE_MANY) {
         return Promise.all(
            params.ids.map(id =>
               httpClient(`${apiUrl}/${resource}/${id}`, {
                  method: 'PUT',
                  body: JSON.stringify(params.data)
               })
            )
         ).then(responses => ({
            data: responses.map(response => response.json)
         }));
      }
      // simple-rest doesn't handle filters on DELETE route, so we fallback to calling DELETE n times instead
      if (type === DELETE_MANY) {
         return Promise.all(
            params.ids.map(id =>
               httpClient(`${apiUrl}/${resource}/${id}`, {
                  method: 'DELETE'
               })
            )
         ).then(responses => ({
            data: responses.map(response => response.json)
         }));
      }

      const { url, options } = convertDataRequestToHTTP(type, resource, params);
      return httpClient(url, options).then(response =>
         convertHTTPResponse(response, type, resource, params)
      );
   };
};

所以现在,当我将数据提供程序指向api端点时,它看起来不像是格式化代码的方式。  我得到了错误

“对'GET_LIST'的响应必须类似于{data:[...]},但是接收到的数据不是数组。dataProvider对于'GET_LIST'可能是错误的”

我在以前的API中广泛使用了此dataprovider,该API返回的数据略有不同。

因为odata返回的对象带有上下文和url作为项目,而值带有数组的第二个对象则不起作用。

我真的只需要数组,但不知道该怎么写。

1 个答案:

答案 0 :(得分:0)

I am also implementing DataProvider for OData and what you need to do is that you have to "wrap" your response data stored in value with data object.

But the array is in value prop and you can't just assert return { data: json }; like you do, because it expects object like {data: [0: {prop1: "hello", prop2: "world"}, 1: { ... }]} and you return this:

{
  "@odata.context":"http://localhost:5001/api/$metadata#apemp",
  "value":[
     {
       "EmpID":1,
       "Abbr":"Admin",
       "BadgeNo":null,
       "ColorRef":0,
       "ContactMethodID":null,
       "DateHired":"2018-05-25T16:42:57-05:00"
     }
  ]
}

So what you need to do is to assign value prop of response json, eg:

return { data: json.value };

So its actually pretty easy to fix