diff --git a/src/Model/collections.ts b/src/Model/collections.ts index 1f9531b9..874000c4 100644 --- a/src/Model/collections.ts +++ b/src/Model/collections.ts @@ -2,6 +2,7 @@ import { Doc } from './Doc'; import { Model, RootModel } from './Model'; import { JSONObject } from 'sharedb/lib/sharedb'; import type { Path, ReadonlyDeep, ShallowCopiedValue, Segments } from '../types'; + var LocalDoc = require('./LocalDoc'); var util = require('../util'); @@ -78,6 +79,14 @@ declare module './Model' { _get(segments: Segments): any; _getCopy(segments: Segments): any; _getDeepCopy(segments: Segments): any; + + /** + * Gets array of values of collection at this model's path or relative subpath + * + * If no values exist at subpath, an empty array is returned + * @param subpath + */ + getValues(subpath?: Path): ReadonlyDeep[]; } } @@ -124,6 +133,17 @@ Model.prototype._getDeepCopy = function(segments) { return util.deepCopy(value); }; +Model.prototype.getValues = function(subpath?: Path) { + const value = this.get(subpath); + if (value == null) { + return []; + } + if (typeof value !== 'object') { + throw new Error(`Found non-object type for getValues('${this.path(subpath)}')`); + } + return Object.values(value) as ReadonlyDeep[]; +} + Model.prototype.getOrCreateCollection = function(name) { var collection = this.root.collections[name]; if (collection) return collection; diff --git a/test/Model/collections.js b/test/Model/collections.js new file mode 100644 index 00000000..1e533706 --- /dev/null +++ b/test/Model/collections.js @@ -0,0 +1,33 @@ +const {expect} = require('../util'); +const {RootModel} = require('../../lib'); + +describe('collections', () => { + describe('getValues', () => { + it('returns array of values from collection', () => { + const model = new RootModel(); + model.add('_test_docs', {name: 'foo'}); + model.add('_test_docs', {name: 'bar'}); + const values = model.getValues('_test_docs'); + expect(values).to.be.instanceOf(Array); + expect(values).to.have.lengthOf(2); + ['foo', 'bar'].forEach((value, index) => { + expect(values[index]).to.have.property('name', value); + }); + }); + + it('return empty array when no values at subpath', () => { + const model = new RootModel(); + const values = model.getValues('_test_docs'); + expect(values).to.be.instanceOf(Array); + expect(values).to.have.lengthOf(0); + }); + + it('throws error if non-object result at path', () => { + const model = new RootModel(); + const id = model.add('_colors', {rgb: 3}); + expect( + () => model.getValues(`_colors.${id}.rgb`) + ).to.throw(`Found non-object type for getValues('_colors.${id}.rgb')`); + }); + }); +});