Skip to content

Commit ae5d64a

Browse files
authored
Support fetchAllIfNeededWithInclude (#900)
1 parent f9a397b commit ae5d64a

File tree

2 files changed

+86
-12
lines changed

2 files changed

+86
-12
lines changed

integration/test/ParseObjectTest.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,37 @@ describe('Parse Object', () => {
14481448
}).catch(done.fail);
14491449
});
14501450

1451+
it('can fetchAllIfNeededWithInclude', async () => {
1452+
const pointer = new TestObject({ foo: 'bar' });
1453+
const item1 = new Item({ x: 1});
1454+
const item2 = new Item({ x: 2, pointer });
1455+
const items = [item1, item2];
1456+
1457+
await Parse.Object.saveAll(items);
1458+
1459+
const container = new Container();
1460+
container.set('items', items);
1461+
await container.save();
1462+
1463+
const query = new Parse.Query(Container);
1464+
const containerAgain = await query.get(container.id);
1465+
1466+
// Fetch objects with no data
1467+
const itemsAgain = containerAgain.get('items');
1468+
const item1Again = itemsAgain[0].set('x', 100);
1469+
const item2Again = itemsAgain[1];
1470+
1471+
// Override item1 in database, this shouldn't fetch
1472+
await item1Again.save();
1473+
1474+
const fetchedItems = await Parse.Object.fetchAllIfNeededWithInclude([item1, item2Again], ['pointer']);
1475+
assert.equal(fetchedItems.length, items.length);
1476+
assert.equal(fetchedItems[0].get('x'), 1);
1477+
assert.equal(fetchedItems[1].get('x'), 2); // item2Again should update
1478+
assert.equal(fetchedItems[1].get('pointer').id, pointer.id);
1479+
assert.equal(fetchedItems[1].get('pointer').get('foo'), 'bar');
1480+
});
1481+
14511482
it('can fetchAllIfNeeded', (done) => {
14521483
const numItems = 11;
14531484
const container = new Container();

src/ParseObject.js

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,18 +1427,7 @@ class ParseObject {
14271427
queryOptions.sessionToken = options.sessionToken;
14281428
}
14291429
if (options.hasOwnProperty('include')) {
1430-
queryOptions.include = [];
1431-
if (Array.isArray(options.include)) {
1432-
options.include.forEach((key) => {
1433-
if (Array.isArray(key)) {
1434-
queryOptions.include = queryOptions.include.concat(key);
1435-
} else {
1436-
queryOptions.include.push(key);
1437-
}
1438-
});
1439-
} else {
1440-
queryOptions.include.push(options.include);
1441-
}
1430+
queryOptions.include = ParseObject.handleIncludeOptions(options);
14421431
}
14431432
return CoreManager.getObjectController().fetch(
14441433
list,
@@ -1481,6 +1470,41 @@ class ParseObject {
14811470
return ParseObject.fetchAll(list, options);
14821471
}
14831472

1473+
/**
1474+
* Fetches the given list of Parse.Object if needed.
1475+
* If any error is encountered, stops and calls the error handler.
1476+
*
1477+
* Includes nested Parse.Objects for the provided key. You can use dot
1478+
* notation to specify which fields in the included object are also fetched.
1479+
*
1480+
* If any error is encountered, stops and calls the error handler.
1481+
*
1482+
* <pre>
1483+
* Parse.Object.fetchAllIfNeededWithInclude([object1, object2, ...], [pointer1, pointer2, ...])
1484+
* .then((list) => {
1485+
* // All the objects were fetched.
1486+
* }, (error) => {
1487+
* // An error occurred while fetching one of the objects.
1488+
* });
1489+
* </pre>
1490+
*
1491+
* @param {Array} list A list of <code>Parse.Object</code>.
1492+
* @param {String|Array<string|Array<string>>} keys The name(s) of the key(s) to include.
1493+
* @param {Object} options
1494+
* Valid options are:<ul>
1495+
* <li>useMasterKey: In Cloud Code and Node only, causes the Master Key to
1496+
* be used for this request.
1497+
* <li>sessionToken: A valid session token, used for making a request on
1498+
* behalf of a specific user.
1499+
* </ul>
1500+
* @static
1501+
*/
1502+
static fetchAllIfNeededWithInclude(list: Array<ParseObject>, keys: String|Array<string|Array<string>>, options: RequestOptions) {
1503+
options = options || {};
1504+
options.include = keys;
1505+
return ParseObject.fetchAllIfNeeded(list, options);
1506+
}
1507+
14841508
/**
14851509
* Fetches the given list of Parse.Object if needed.
14861510
* If any error is encountered, stops and calls the error handler.
@@ -1508,13 +1532,32 @@ class ParseObject {
15081532
if (options.hasOwnProperty('sessionToken')) {
15091533
queryOptions.sessionToken = options.sessionToken;
15101534
}
1535+
if (options.hasOwnProperty('include')) {
1536+
queryOptions.include = ParseObject.handleIncludeOptions(options);
1537+
}
15111538
return CoreManager.getObjectController().fetch(
15121539
list,
15131540
false,
15141541
queryOptions
15151542
);
15161543
}
15171544

1545+
static handleIncludeOptions(options) {
1546+
let include = [];
1547+
if (Array.isArray(options.include)) {
1548+
options.include.forEach((key) => {
1549+
if (Array.isArray(key)) {
1550+
include = include.concat(key);
1551+
} else {
1552+
include.push(key);
1553+
}
1554+
});
1555+
} else {
1556+
include.push(options.include);
1557+
}
1558+
return include;
1559+
}
1560+
15181561
/**
15191562
* Destroy the given list of models on the server if it was already persisted.
15201563
*

0 commit comments

Comments
 (0)