Skip to content

Commit

Permalink
Resources: Pass get control to template (#885)
Browse files Browse the repository at this point in the history
* pass get control to template

* typo
  • Loading branch information
agubler authored Mar 9, 2021
1 parent 2073a03 commit ad9f5e4
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/core/middleware/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ export interface Delete<DATA> {
(items: DATA[]): void;
}

export interface Get<DATA> {
(request: ReadRequest): DATA[] | undefined;
(request: string[]): (undefined | DATA)[];
}

export interface TemplateControls<DATA> {
put: Put<DATA>;
del: Delete<DATA>;
get: Get<DATA>;
}

export interface TemplateRead<DATA> {
Expand Down Expand Up @@ -792,7 +798,34 @@ const middleware = factory(
});
};

(instance as any)[key](args, { put, del });
const get = (request: ReadOptionsData | string[]) => {
if (Array.isArray(request)) {
return request.map((id) => {
const [synthId] = cache.getSyntheticIds(id);
if (synthId) {
const item = cache.get(synthId);
if (item) {
return item.value;
}
}
});
}
let items: (undefined | any)[] = [];
const { offset, size, query } = request;
const end = offset + size;
for (let i = 0; i < end - offset; i++) {
const item = cache.get({ requestId: JSON.stringify(query), orderId: `${offset + i}` });
if (!item || item.status === 'pending') {
return;
}
if (item && item.status === 'resolved') {
items.push(transformData(item.value, transform));
}
}
return items;
};

(instance as any)[key](args, { put, del, get });
};
return api;
},
Expand Down
40 changes: 40 additions & 0 deletions tests/core/unit/middleware/resources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1982,6 +1982,46 @@ jsdomDescribe('Resources Middleware', () => {
'<div>[{"value":10},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]</div>'
);
});

it('Should be able to use `get` passed to the template controls', () => {
const root = document.createElement('div');
const testTemplate = createResourceTemplate<
TestData & { label: string },
DefaultApi & { update: (id: string) => void }
>({
idKey: 'value',
read: (req, { get, put }) => {
const item = get(req);
if (item) {
put({ data: item, total: 1 }, req);
} else {
put({ data: [{ value: '1', label: 'Original' }], total: 1 }, req);
}
},
update: (id, { get, put }) => {
const [item] = get([id]);
if (item) {
put([{ ...item, label: 'Updated' }]);
}
}
});

const App = create({ resource: createResourceMiddleware() })(({ id, middleware: { resource } }) => {
const {
get,
createOptions,
template: { update, read }
} = resource.template(testTemplate);
get(createOptions(() => ({}))(), { read });
update('1');
const item = get(createOptions(() => ({}))(), { read });
return <div>{JSON.stringify(item)}</div>;
});

const r = renderer(() => <App />);
r.mount({ domNode: root });
assert.strictEqual(root.innerHTML, '<div>[{"value":"1","label":"Updated"}]</div>');
});
});
describe('Custom Api', () => {
it('Should support using a template with a custom api', () => {
Expand Down

0 comments on commit ad9f5e4

Please sign in to comment.