Skip to content

Commit

Permalink
fix #7904 (#7949)
Browse files Browse the repository at this point in the history
  • Loading branch information
runspired authored Apr 14, 2022
1 parent 32e9c79 commit beac4f1
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { A } from '@ember/array';
import { w } from '@ember/string';
import EmberObject, { computed } from '@ember/object';
import { filterBy } from '@ember/object/computed';
import { settled } from '@ember/test-helpers';

import { module, test } from 'qunit';

import { setupRenderingTest } from 'ember-qunit';

import Model, { attr, hasMany } from '@ember-data/model';

module('PromiseManyArray side-affected by EmberArray', (hooks) => {
module('PromiseManyArray', (hooks) => {
setupRenderingTest(hooks);

test('PromiseManyArray is not side-affected by EmberArray', async function (assert) {
Expand All @@ -16,12 +18,12 @@ module('PromiseManyArray side-affected by EmberArray', (hooks) => {
@attr('string') name;
}
class Group extends Model {
@hasMany('person', { inverse: null }) members;
@hasMany('person', { async: true, inverse: null }) members;
}
owner.register('model:person', Person);
owner.register('model:group', Group);
const store = owner.lookup('service:store');
const members = w('Bob John Michael Larry Lucy').map((name) => store.createRecord('person', { name }));
const members = ['Bob', 'John', 'Michael', 'Larry', 'Lucy'].map((name) => store.createRecord('person', { name }));
const group = store.createRecord('group', { members });

const replaceFn = group.members.replace;
Expand All @@ -36,4 +38,85 @@ module('PromiseManyArray side-affected by EmberArray', (hooks) => {
group.members.replace(0, 1);
assert.strictEqual(group.members.length, 3, 'updated length is correct');
});

test('PromiseManyArray can be subscribed to by computed chains', async function (assert) {
const { owner } = this;
class Person extends Model {
@attr('string') name;
}
class Group extends Model {
@hasMany('person', { async: true, inverse: null }) members;

@computed('[email protected]')
get memberIds() {
return this.members.map((m) => m.id);
}

@filterBy('members', 'name', 'John')
johns;
}
owner.register('model:person', Person);
owner.register('model:group', Group);
owner.register(
'serializer:application',
class extends EmberObject {
normalizeResponse(_, __, data) {
return data;
}
}
);

let _id = 0;
const names = ['Bob', 'John', 'Michael', 'John', 'Larry', 'Lucy'];
owner.register(
'adapter:application',
class extends EmberObject {
findRecord() {
const name = names[_id++];
const data = {
type: 'person',
id: `${_id}`,
attributes: {
name,
},
};
return { data };
}
}
);
const store = owner.lookup('service:store');

const group = store.push({
data: {
type: 'group',
id: '1',
relationships: {
members: {
data: [
{ type: 'person', id: '1' },
{ type: 'person', id: '2' },
{ type: 'person', id: '3' },
{ type: 'person', id: '4' },
{ type: 'person', id: '5' },
{ type: 'person', id: '6' },
],
},
},
},
});

// access the group data
let memberIds = group.memberIds;
let johnRecords = group.johns;
assert.strictEqual(memberIds.length, 0, 'member ids is 0 initially');
assert.strictEqual(johnRecords.length, 0, 'john ids is 0 initially');

await settled();

memberIds = group.memberIds;
johnRecords = group.johns;
assert.strictEqual(memberIds.length, 6, 'memberIds length is correct');
assert.strictEqual(johnRecords.length, 2, 'johnRecords length is correct');
assert.strictEqual(group.members.length, 6, 'members length is correct');
});
});
3 changes: 3 additions & 0 deletions packages/model/addon/-private/system/promise-many-array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export default class PromiseManyArray {
*/
@dependentKeyCompat
get length(): number {
// shouldn't be needed, but ends up being needed
// for computed chains even in 4.x
this['[]'];
return this.content ? this.content.length : 0;
}

Expand Down

0 comments on commit beac4f1

Please sign in to comment.