Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -1951,6 +1951,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