Skip to content

Commit

Permalink
fix: use join vs run for deleteRecord destroy of new records
Browse files Browse the repository at this point in the history
  • Loading branch information
runspired committed Nov 15, 2022
1 parent 2a9a25e commit dcfb5de
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 3 deletions.
4 changes: 2 additions & 2 deletions packages/store/addon/-private/store-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { getOwner, setOwner } from '@ember/application';
import { assert, deprecate } from '@ember/debug';
import { _backburner as emberBackburner, run } from '@ember/runloop';
import { _backburner as emberBackburner } from '@ember/runloop';
import Service from '@ember/service';
import { registerWaiter, unregisterWaiter } from '@ember/test';
import { DEBUG } from '@glimmer/env';
Expand Down Expand Up @@ -642,7 +642,7 @@ class Store extends Service {
recordData.setIsDeleted(identifier, true);

if (recordData.isNew(identifier)) {
run(() => {
emberBackburner.join(() => {
this._instanceCache.unloadRecord(identifier);
});
}
Expand Down
97 changes: 96 additions & 1 deletion tests/main/tests/acceptance/relationships/has-many-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ArrayProxy from '@ember/array/proxy';
import { action } from '@ember/object';
import { sort } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import { click, find, findAll, render } from '@ember/test-helpers';
import { click, find, findAll, render, rerender } from '@ember/test-helpers';
import Component from '@glimmer/component';
import Ember from 'ember';

Expand Down Expand Up @@ -1211,6 +1211,101 @@ module('autotracking has-many', function (hooks) {
assert.deepEqual(names, ['RGB', 'RGB'], 'rendered 2 children');
});

test('We can re-render hasMany with filter after deleting a record', async function (assert) {
this.owner.register(
'model:person',
class extends Model {
@attr name;
@hasMany('person', { async: false, inverse: 'parent' })
children;
@belongsTo('person', { async: false, inverse: 'children' })
parent;
}
);
class ChildrenList extends Component {
@service store;

get children() {
return this.args.children.filter((x) => !x.isDeleted);
}

@action
createChild() {
const parent = this.args.person;
const name = 'RGB';
this.store.createRecord('person', { name, parent });
}

@action
deleteChild(child) {
child.deleteRecord();
}
}

let layout = hbs`
<button id="createChild" {{on "click" this.createChild}}>Add child</button>
<h2>{{this.children.length}}</h2>
<ul>
{{#each this.children as |child|}}
<li><span>{{child.name}}</span><button class="delete-child" {{on "click" (fn this.deleteChild child)}}>X</button></li>
{{/each}}
</ul>
`;
this.owner.register('component:children-list', ChildrenList);
this.owner.register('template:components/children-list', layout);

this.person = store.push({
data: {
type: 'person',
id: '1',
attributes: { name: 'Doodad' },
},
});
this.children = await this.person.children;

await render(hbs`<ChildrenList @children={{this.children}} @person={{this.person}} />`);

let names = findAll('li > span').map((e) => e.textContent);

assert.deepEqual(names, [], 'rendered no children');

store.push({
data: {
type: 'person',
id: '2',
attributes: { name: 'Rey' },
relationships: {
parent: { data: { id: '1', type: 'person' } },
},
},
});
await rerender();

names = findAll('li > span').map((e) => e.textContent);
assert.deepEqual(names, ['Rey'], 'rendered one child');

await click('#createChild');

names = findAll('li > span').map((e) => e.textContent);
assert.deepEqual(names, ['Rey', 'RGB'], 'rendered 1 existing and 1 created child');

await click('#createChild');

names = findAll('li > span').map((e) => e.textContent);
assert.deepEqual(names, ['Rey', 'RGB', 'RGB'], 'rendered 1 existing and 2 created children');

await click(find('.delete-child'));

names = findAll('li > span').map((e) => e.textContent);
assert.deepEqual(names, ['RGB', 'RGB'], 'rendered 2 created children after deleting existing');

await click(find('.delete-child'));

names = findAll('li > span').map((e) => e.textContent);
assert.deepEqual(names, ['RGB'], 'rendered 1 created children after deleting existing');
});

test('We can re-render hasMany with peekAll', async function (assert) {
class PeopleList extends Component {
@service store;
Expand Down

0 comments on commit dcfb5de

Please sign in to comment.