Skip to content

Commit

Permalink
fix(core): fix assigning embedded arrays
Browse files Browse the repository at this point in the history
Closes #1699
  • Loading branch information
B4nan committed Apr 18, 2021
1 parent 65a71b8 commit 9ee8f5c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
15 changes: 14 additions & 1 deletion packages/core/src/entity/EntityAssigner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,26 @@ export class EntityAssigner {
private static assignEmbeddable<T extends AnyEntity<T>>(entity: T, value: any, prop: EntityProperty, em: EntityManager, options: AssignOptions): void {
const Embeddable = prop.embeddable;
const propName = prop.embedded ? prop.embedded[1] : prop.name;
entity[propName] = options.mergeObjects ? entity[propName] || Object.create(Embeddable.prototype) : Object.create(Embeddable.prototype);
entity[propName] = prop.array || options.mergeObjects ? (entity[propName] || Object.create(Embeddable.prototype)) : Object.create(Embeddable.prototype);

if (!value) {
entity[propName] = value;
return;
}

// if the value is not an array, we just push, otherwise we replace the array
if (prop.array && (Array.isArray(value) || entity[propName] == null)) {
entity[propName] = [];
}

if (prop.array) {
return Utils.asArray(value).forEach(item => {
const tmp = {};
this.assignEmbeddable(tmp, item, { ...prop, array: false }, em, options);
entity[propName].push(...Object.values(tmp));
});
}

Object.keys(value).forEach(key => {
const childProp = prop.embeddedProps[key];

Expand Down
25 changes: 25 additions & 0 deletions tests/features/embeddables/embedded-entities.postgres.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,31 @@ describe('embedded entities in postgresql', () => {
await expect(orm.getSchemaGenerator().getDropSchemaSQL(false)).resolves.toMatchSnapshot('embeddables 3');
});

test('assigning to array embeddables (GH #1699)', async () => {
const user = new User();
expect(user.addresses).toEqual([]);
const address1 = new Address1('Downing street 13A', 10, '10A', 'London 4A', 'UK 4A');
const address2 = { street: 'Downing street 23A', number: 20, postalCode: '20A', city: 'London 24A', country: 'UK 24A' };

wrap(user).assign({ addresses: [address1] }, { mergeObjects: true });
expect(user.addresses).toEqual([address1]);
expect(user.addresses[0]).toBeInstanceOf(Address1);

wrap(user).assign({ addresses: [address1] }, { mergeObjects: true, updateNestedEntities: true });
expect(user.addresses).toEqual([address1]);
expect(user.addresses[0]).toBeInstanceOf(Address1);

wrap(user).assign({ addresses: [address2] });
expect(user.addresses).toEqual([address2]);
expect(user.addresses[0]).toBeInstanceOf(Address1);

wrap(user).assign({ addresses: address1 }); // push to existing array
expect(user.addresses).toEqual([address2, address1]);
expect(user.addresses[0]).toBeInstanceOf(Address1);
expect(user.addresses[1]).toBeInstanceOf(Address1);
expect(user.addresses).toHaveLength(2);
});

test('persist and load', async () => {
const user = new User();
user.address1 = new Address1('Downing street 10', 10, '123', 'London 1', 'UK 1');
Expand Down

0 comments on commit 9ee8f5c

Please sign in to comment.