Skip to content

Commit

Permalink
FIX RxDocument getter should return the same object on property paths [
Browse files Browse the repository at this point in the history
  • Loading branch information
pubkey authored Mar 12, 2023
1 parent c9d3573 commit e32f260
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 5 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# RxDB Changelog

<!-- CHANGELOG NEWEST -->

- FIX RxDocument getter should return the same object on property paths [#4548](https://github.com/pubkey/rxdb/pull/4548)
<!-- ADD new changes here! -->

<!-- /CHANGELOG NEWEST -->
Expand Down
17 changes: 14 additions & 3 deletions src/rx-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,19 @@ export const basePrototype = {
return refCollection.findOne(value).exec();
}
},

/**
* get data by objectPath
*/
get(this: RxDocument, objPath: string): any | null {
if (!this._data) return undefined;
if (!this._data) {
return undefined;
}

const fromCache = this._propertyCache.get(objPath);
if (fromCache) {
return fromCache;
}

let valueObj = getProperty(this._data, objPath);

// direct return if array or non-object
Expand All @@ -209,6 +216,7 @@ export const basePrototype = {
objPath,
this as any
);
this._propertyCache.set(objPath, valueObj);
return valueObj;
},

Expand Down Expand Up @@ -406,6 +414,7 @@ export function createRxDocumentConstructor(proto = basePrototype) {

// assume that this is always equal to the doc-data in the database
this._data = docData;
this._propertyCache = new Map<string, any>();

/**
* because of the prototype-merge,
Expand All @@ -423,7 +432,9 @@ export function defineGetterSetter(
objPath = '',
thisObj = false
) {
if (valueObj === null) return;
if (valueObj === null) {
return;
}


let pathProperties = getSchemaByObjectPath(
Expand Down
5 changes: 5 additions & 0 deletions src/types/rx-document.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ export declare interface RxDocumentBase<RxDocType, OrmMethods = {}> {
_data: RxDocumentData<RxDocType>;
primaryPath: string;
revision: string;
/**
* Used to de-duplicate the enriched property objects
* of the document.
*/
_propertyCache: Map<string, any>;
$emit(cE: RxChangeEvent<RxDocType>): void;
_saveData(newData: any, oldData: any): Promise<RxDocument<RxDocType, OrmMethods>>;
// /internal things
Expand Down
26 changes: 25 additions & 1 deletion test/unit/reactive-document.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from '../../';

import {
first
first,
} from 'rxjs/operators';
import type {
RxChangeEvent
Expand Down Expand Up @@ -195,5 +195,29 @@ config.parallel('reactive-document.test.js', () => {
});
});
describe('issues', () => {
it('#4546 - should return the same valueObj for the same objPath', async () => {
const c = await humansCollection.createNested();
const doc = await c.findOne().exec(true);

// Call get function multiple times with the same objPath
const firstValueObject = doc.mainSkill;
const valueObjects: typeof firstValueObject[] = [];
valueObjects.push(doc.get('mainSkill'));
valueObjects.push(doc.get('mainSkill'));
valueObjects.push(doc.get('mainSkill'));

// also check subscription values
valueObjects.push(await firstValueFrom(doc.get$('mainSkill')));
valueObjects.push(await firstValueFrom(doc.get$('mainSkill')));



// Ensure that all returned valueObjs are the same object using Object.is comparison
valueObjects.forEach(obj => {
assert.equal(Object.is(firstValueObject, obj), true);
});

c.database.destroy();
});
});
});

0 comments on commit e32f260

Please sign in to comment.