Skip to content

Commit

Permalink
[feature] modifying update call to only update changed fields. (#123)
Browse files Browse the repository at this point in the history
  • Loading branch information
kav authored Feb 23, 2024
1 parent 2b830a0 commit 6431d4b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 9 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"ra-core": "^4.1.0"
},
"dependencies": {
"lodash.isequal": "^4.5.0",
"qs": "^6.11.1"
}
}
24 changes: 18 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
encodeId,
} from './urlBuilder';
import qs from 'qs';
import isEqual from 'lodash/isEqual';

/**
* Maps react-admin queries to a postgrest REST API
Expand Down Expand Up @@ -146,8 +147,8 @@ export default (config: IDataProviderConfig): DataProvider => ({
return config.httpClient(url, options).then(({ headers, json }) => {
if (!headers.has('content-range')) {
throw new Error(
`The Content-Range header is missing in the HTTP Response. The postgREST data provider expects
responses for lists of resources to contain this header with the total number of results to build
`The Content-Range header is missing in the HTTP Response. The postgREST 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?`
);
}
Expand Down Expand Up @@ -249,8 +250,8 @@ export default (config: IDataProviderConfig): DataProvider => ({
return config.httpClient(url, options).then(({ headers, json }) => {
if (!headers.has('content-range')) {
throw new Error(
`The Content-Range header is missing in the HTTP Response. The postgREST data provider expects
responses for lists of resources to contain this header with the total number of results to build
`The Content-Range header is missing in the HTTP Response. The postgREST 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?`
);
}
Expand All @@ -265,15 +266,16 @@ export default (config: IDataProviderConfig): DataProvider => ({
},

update: (resource, params: Partial<UpdateParams> = {}) => {
const { id, data, meta } = params;
const { id, data, meta, previousData } = params;
const primaryKey = getPrimaryKey(resource, config.primaryKeys);
const query = getQuery(primaryKey, id, resource, meta);
const url = `${config.apiUrl}/${resource}?${qs.stringify(query)}`;
const changedData = getChanges(data, previousData);
const metaSchema = params.meta?.schema;

const body = JSON.stringify({
...dataWithoutVirtualId(
removePrimaryKey(data, primaryKey),
removePrimaryKey(changedData, primaryKey),
primaryKey
),
});
Expand Down Expand Up @@ -406,3 +408,13 @@ export default (config: IDataProviderConfig): DataProvider => ({
}));
},
});

const getChanges = (data: any, previousData: any) => {
const changes = Object.keys(data).reduce((changes, key) => {
if (!isEqual(data[key], previousData[key])) {
changes[key] = data[key];
}
return changes;
}, {});
return changes;
};
9 changes: 6 additions & 3 deletions tests/dataProvider/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ describe('update specific', () => {
resource: 'contacts',
params: {
id: JSON.stringify([1, 'X']),
data: { name: 'new name' },
data: { name: 'new name', unchanged: 'value' },
previousData: { name: 'old name', unchanged: 'value' },
meta: {},
},
expectedUrl: '/contacts?'.concat(qs.stringify({and: '(id.eq.1,type.eq.X)'})),
expectedUrl: '/contacts?'.concat(
qs.stringify({ and: '(id.eq.1,type.eq.X)' })
),
expectedOptions: {
method: 'PATCH',
body: JSON.stringify({ name: 'new name' }),
Expand All @@ -24,7 +27,7 @@ describe('update specific', () => {
'content-type': 'application/json',
},
},
}
},
];

cases.forEach(makeTestFromCase);
Expand Down

0 comments on commit 6431d4b

Please sign in to comment.