diff --git a/History.md b/History.md index 8c974da9b5..e55edd7133 100644 --- a/History.md +++ b/History.md @@ -1,5 +1,9 @@ ## v.NEXT +* Minimongo cursors are now JavaScript iterable objects and can now be iterated over + using `for...of` loops, spread operator, `yield*`, and destructuring assignments. + [PR #8888](https://github.com/meteor/meteor/pull/8888) + * `meteor list --tree` can now be used to list all transitive package dependencies (and versions) in an application. Weakly referenced dependencies can also be listed by using the `--weak` option. For more information, run diff --git a/packages/minimongo/cursor.js b/packages/minimongo/cursor.js index 6655f1f3ea..89d135b82b 100644 --- a/packages/minimongo/cursor.js +++ b/packages/minimongo/cursor.js @@ -72,6 +72,35 @@ export default class Cursor { return result; } + [Symbol.iterator]() { + if (this.reactive) { + this._depend({ + addedBefore: true, + removed: true, + changed: true, + movedBefore: true}); + } + + let index = 0; + const objects = this._getRawObjects({ordered: true}); + + return { + next: () => { + if (index < objects.length) { + // This doubles as a clone operation. + let element = this._projectionFn(objects[index++]); + + if (this._transform) + element = this._transform(element); + + return {value: element}; + } + + return {done: true}; + } + }; + } + /** * @callback IterationCallback * @param {Object} doc diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 430b4c084e..ca912ab0e8 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -220,6 +220,17 @@ Tinytest.add('minimongo - cursors', test => { // call it again, it still works test.length(q.fetch(), 20); + // iterator + count = 0; + for (let obj of q) { + test.equal(obj.i, count++); + }; + test.equal(count, 20); + // call it again, it still works + test.length(q.fetch(), 20); + // test spread operator + test.equal([...q], q.fetch()); + // map res = q.map(function(obj, i, cursor) { test.equal(obj.i, i);