Skip to content

Commit

Permalink
Merge pull request #306 from derbyjs/getValues
Browse files Browse the repository at this point in the history
Add getValues method for fetching array of docs from collection
  • Loading branch information
craigbeck authored May 24, 2024
2 parents 3e0d499 + 519ee80 commit d40585b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/Model/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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<S>(subpath?: Path): ReadonlyDeep<S>[];
}
}

Expand Down Expand Up @@ -124,6 +133,17 @@ Model.prototype._getDeepCopy = function(segments) {
return util.deepCopy(value);
};

Model.prototype.getValues = function<S>(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<S>[];
}

Model.prototype.getOrCreateCollection = function(name) {
var collection = this.root.collections[name];
if (collection) return collection;
Expand Down
33 changes: 33 additions & 0 deletions test/Model/collections.js
Original file line number Diff line number Diff line change
@@ -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')`);
});
});
});

0 comments on commit d40585b

Please sign in to comment.