Skip to content

Commit

Permalink
use batchLoadFn.apply instead of directly invoking batchLoadFn (#182)
Browse files Browse the repository at this point in the history
* use batchLoadFn.apply instead of directly invoking batchLoadFn

use batchLoadFn.apply(loader,[keys]) instead of batchLoadFn(keys) to allow acces to the actual dataloader. Needed for example to use dataloader.prime() in the batch loader function.

* Add tests
  • Loading branch information
jorisroling authored and leebyron committed Nov 13, 2019
1 parent cffec0e commit bb8a7aa
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,19 @@ minimal outgoing data requests.
#### Batch Function

A batch loading function accepts an Array of keys, and returns a Promise which
resolves to an Array of values. There are a few constraints that must be upheld:
resolves to an Array of values or Error instances. The loader itself is provided
as the `this` context.

```js
async function batchFunction(keys) {
const results = await db.fetchAllKeys(keys)
return keys.map(key => results[key] || new Error(`No result for ${key}`))
}

const loader = new DataLoader(batchFunction)
```

There are a few constraints this function must uphold:

* The Array of values must be the same length as the Array of keys.
* Each index in the Array of values must correspond to the same index in the Array of keys.
Expand All @@ -116,7 +128,7 @@ with the original keys `[ 2, 9, 6, 1 ]`:
[
{ id: 2, name: 'San Francisco' },
{ id: 9, name: 'Chicago' },
null,
null, // or perhaps `new Error()`
{ id: 1, name: 'New York' }
]
```
Expand Down
13 changes: 13 additions & 0 deletions src/__tests__/dataloader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ describe('Primary API', () => {
expect(value1).toBe(1);
});

it('references the loader as "this" in the batch function', async () => {
let that;
const loader = new DataLoader(async function (keys) {
that = this;
return keys;
});

// Trigger the batch function
await loader.load(1);

expect(that).toBe(loader);
});

it('supports loading multiple keys in one call', async () => {
const identityLoader = new DataLoader(keys => Promise.resolve(keys));

Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ function dispatchQueueBatch<K, V>(

// Call the provided batchLoadFn for this loader with the loader queue's keys.
var batchLoadFn = loader._batchLoadFn;
var batchPromise = batchLoadFn(keys);
// Call with the loader as the `this` context.
var batchPromise = batchLoadFn.call(loader, keys);

// Assert the expected response from batchLoadFn
if (!batchPromise || typeof batchPromise.then !== 'function') {
Expand Down

0 comments on commit bb8a7aa

Please sign in to comment.