diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 334ac1b62c..a2340e9eb6 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -1422,6 +1422,78 @@ describe('Parse.Query testing', () => { }); }); + it('properly includes array', (done) => { + let objects = []; + let total = 0; + while(objects.length != 5) { + let object = new Parse.Object('AnObject'); + object.set('key', objects.length); + total += objects.length; + objects.push(object); + } + Parse.Object.saveAll(objects).then(() => { + let object = new Parse.Object("AContainer"); + object.set('objects', objects); + return object.save(); + }).then(() => { + let query = new Parse.Query('AContainer'); + query.include('objects'); + return query.find() + }).then((results) => { + expect(results.length).toBe(1); + let res = results[0]; + let objects = res.get('objects'); + expect(objects.length).toBe(5); + objects.forEach((object) => { + total -= object.get('key'); + }); + expect(total).toBe(0); + done() + }, () => { + fail('should not fail'); + done(); + }) + }); + + it('properly includes array of mixed objects', (done) => { + let objects = []; + let total = 0; + while(objects.length != 5) { + let object = new Parse.Object('AnObject'); + object.set('key', objects.length); + total += objects.length; + objects.push(object); + } + while(objects.length != 10) { + let object = new Parse.Object('AnotherObject'); + object.set('key', objects.length); + total += objects.length; + objects.push(object); + } + Parse.Object.saveAll(objects).then(() => { + let object = new Parse.Object("AContainer"); + object.set('objects', objects); + return object.save(); + }).then(() => { + let query = new Parse.Query('AContainer'); + query.include('objects'); + return query.find() + }).then((results) => { + expect(results.length).toBe(1); + let res = results[0]; + let objects = res.get('objects'); + expect(objects.length).toBe(10); + objects.forEach((object) => { + total -= object.get('key'); + }); + expect(total).toBe(0); + done() + }, (err) => { + fail('should not fail'); + done(); + }) + }) + it("result object creation uses current extension", function(done) { var ParentObject = Parse.Object.extend({ className: "ParentObject" }); // Add a foo() method to ChildObject. diff --git a/src/RestQuery.js b/src/RestQuery.js index 8cfd26df86..f2636b54c1 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -449,39 +449,42 @@ function includePath(config, auth, response, path) { if (pointers.length == 0) { return response; } + let pointersHash = {}; var className = null; var objectIds = {}; for (var pointer of pointers) { - if (className === null) { - className = pointer.className; - } else { - if (className != pointer.className) { - throw new Parse.Error(Parse.Error.INVALID_JSON, - 'inconsistent type data for include'); - } + let className = pointer.className; + // only include the good pointers + if (className) { + pointersHash[className] = pointersHash[className] || []; + pointersHash[className].push(pointer.objectId); } - objectIds[pointer.objectId] = true; - } - if (!className) { - throw new Parse.Error(Parse.Error.INVALID_JSON, - 'bad pointers'); } + let queryPromises = Object.keys(pointersHash).map((className) => { + var where = {'objectId': {'$in': pointersHash[className]}}; + var query = new RestQuery(config, auth, className, where); + return query.execute().then((results) => { + results.className = className; + return Promise.resolve(results); + }) + }) + // Get the objects for all these object ids - var where = {'objectId': {'$in': Object.keys(objectIds)}}; - var query = new RestQuery(config, auth, className, where); - return query.execute().then((includeResponse) => { - var replace = {}; - for (var obj of includeResponse.results) { - obj.__type = 'Object'; - obj.className = className; - - if(className == "_User"){ - delete obj.sessionToken; + return Promise.all(queryPromises).then((responses) => { + var replace = responses.reduce((replace, includeResponse) => { + for (var obj of includeResponse.results) { + obj.__type = 'Object'; + obj.className = includeResponse.className; + + if(className == "_User"){ + delete obj.sessionToken; + } + replace[obj.objectId] = obj; } + return replace; + }, {}) - replace[obj.objectId] = obj; - } var resp = { results: replacePointers(response.results, path, replace) };