From 70f7466b92f7320396c5d8796456ec2ab1b2c2ca Mon Sep 17 00:00:00 2001 From: Chris Bonser Date: Mon, 20 Jun 2022 15:05:45 -0500 Subject: [PATCH 1/3] Increase complexity via forks to try recreating removed from cache errors --- .tool-versions | 1 + app/components/planet-list.hbs | 51 ++++++++------------- app/components/planet-list.js | 16 +++---- app/components/planet.hbs | 43 +++++++++++++++++ app/components/planet.js | 34 ++++++++++++++ tests/integration/components/planet-test.js | 26 +++++++++++ 6 files changed, 132 insertions(+), 39 deletions(-) create mode 100644 .tool-versions create mode 100644 app/components/planet.hbs create mode 100644 app/components/planet.js create mode 100644 tests/integration/components/planet-test.js diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..ba4cc25 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +nodejs 16.13.1 diff --git a/app/components/planet-list.hbs b/app/components/planet-list.hbs index 4f72565..19710bb 100644 --- a/app/components/planet-list.hbs +++ b/app/components/planet-list.hbs @@ -2,23 +2,7 @@
live query
{{#each this.planets as |planet|}} -
-
-
{{planet.name}}
- - -
- {{#each planet.moons as |moon i|}} -
{{i}}: {{moon.name}}
- {{/each}} -
+ {{/each}}
@@ -26,22 +10,27 @@
static query
- +
+ + + +
{{#each this.staticPlanets as |planet|}} -
-
{{planet.name}}
- {{#each planet.moons as |moon i|}} -
{{i}}: {{moon.name}}
- {{/each}} -
+ {{/each}} diff --git a/app/components/planet-list.js b/app/components/planet-list.js index 1163324..097a01b 100644 --- a/app/components/planet-list.js +++ b/app/components/planet-list.js @@ -2,26 +2,26 @@ import Component from '@glimmer/component'; import { inject as service } from '@ember/service'; import { tracked } from '@glimmer/tracking'; import { dropTask } from 'ember-concurrency'; +import { action } from '@ember/object'; export default class PlanetListComponent extends Component { @service store; @tracked staticPlanets = []; + @tracked displayMoons = false; get planets() { return this.store.cache.liveQuery((q) => q.findRecords('planet')); } - /* eslint require-yield: off */ - @dropTask - *refresh() { - this.staticPlanets = this.store.cache.findRecords('planet'); + @action + toggleMoons() { + this.displayMoons = !this.displayMoons; } + /* eslint require-yield: off */ @dropTask - *remove(planet) { + *refresh() { let fork = this.store.fork(); - yield fork.removeRecord(planet); - yield this.store.merge(fork); - fork.destroy(); + this.staticPlanets = fork.cache.findRecords('planet'); } } diff --git a/app/components/planet.hbs b/app/components/planet.hbs new file mode 100644 index 0000000..d7d51b9 --- /dev/null +++ b/app/components/planet.hbs @@ -0,0 +1,43 @@ +
+
+
+ {{#if this.displayEditor}} + + {{else}} + {{@planet.name}} + {{/if}} +
+ +
+ + + +
+
+ + {{#if @displayMoons}} + {{#each @planet.moons as |moon i|}} +
{{i}}: {{moon.name}}
+ {{/each}} + {{/if}} +
diff --git a/app/components/planet.js b/app/components/planet.js new file mode 100644 index 0000000..be8fead --- /dev/null +++ b/app/components/planet.js @@ -0,0 +1,34 @@ +import Component from '@glimmer/component'; +import { inject as service } from '@ember/service'; +import { dropTask } from 'ember-concurrency'; +import { tracked } from '@glimmer/tracking'; + +export default class PlanetComponent extends Component { + @service store; + + @tracked displayEditor = false; + @tracked name = ''; + + @dropTask + *toggleEditor() { + if (this.displayEditor) { + let fork = this.store.fork(); + let planet = fork.cache.findRecord(this.args.planet); + planet.name = this.name; + yield this.store.merge(fork); + fork.destroy(); + } else { + this.name = this.args.planet.name; + } + + this.displayEditor = !this.displayEditor; + } + + @dropTask + *remove(planet) { + let fork = this.store.fork(); + yield fork.removeRecord(planet); + yield this.store.merge(fork); + fork.destroy(); + } +} diff --git a/tests/integration/components/planet-test.js b/tests/integration/components/planet-test.js new file mode 100644 index 0000000..388fc09 --- /dev/null +++ b/tests/integration/components/planet-test.js @@ -0,0 +1,26 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | planet', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs``); + + assert.dom(this.element).hasText(''); + + // Template block usage: + await render(hbs` + + template block text + + `); + + assert.dom(this.element).hasText('template block text'); + }); +}); From 226f9442f33a566ec3e24c130b44454d78418d3f Mon Sep 17 00:00:00 2001 From: Chris Bonser Date: Tue, 21 Jun 2022 07:12:12 -0500 Subject: [PATCH 2/3] try recreating using mirage --- app/components/planet-list.hbs | 13 ++++++++++++- app/components/planet-list.js | 5 +++++ app/routes/application.js | 4 ++++ mirage/scenarios/default.js | 11 ++++------- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/app/components/planet-list.hbs b/app/components/planet-list.hbs index 19710bb..1f27ac5 100644 --- a/app/components/planet-list.hbs +++ b/app/components/planet-list.hbs @@ -1,5 +1,16 @@
-
live query
+
+
live query
+ + +
{{#each this.planets as |planet|}} diff --git a/app/components/planet-list.js b/app/components/planet-list.js index 097a01b..ce7c360 100644 --- a/app/components/planet-list.js +++ b/app/components/planet-list.js @@ -24,4 +24,9 @@ export default class PlanetListComponent extends Component { let fork = this.store.fork(); this.staticPlanets = fork.cache.findRecords('planet'); } + + @dropTask + *reload() { + yield this.store.findRecords('planet', { include: ['moons'] }); + } } diff --git a/app/routes/application.js b/app/routes/application.js index b5c65b8..ccfb619 100644 --- a/app/routes/application.js +++ b/app/routes/application.js @@ -5,6 +5,10 @@ export default class ApplicationRoute extends Route { @service dataCoordinator; @service store; + model() { + return this.store.findRecords('planet', { include: ['moons'] }); + } + async beforeModel() { // Populate the store from backup prior to activating the coordinator // As users browse more data this way of loading the store would diff --git a/mirage/scenarios/default.js b/mirage/scenarios/default.js index adb3af4..35db98b 100644 --- a/mirage/scenarios/default.js +++ b/mirage/scenarios/default.js @@ -1,9 +1,6 @@ -export default function(/* server */) { +export default function (server) { + window.mirage = { server: server }; - /* - Seed your development database using your factories. - This data will not be loaded in your tests. - */ - - // server.createList('post', 10); + let planet = server.create('planet', { name: 'Earth' }); + server.create('moon', { planet: planet, name: 'moon' }); } From ad39a895cb64436abb6f00c170d438efd1364e05 Mon Sep 17 00:00:00 2001 From: Chris Bonser Date: Tue, 21 Jun 2022 08:16:48 -0500 Subject: [PATCH 3/3] Using a forking + rebase pattern will recreate the issue consistently. Do not attempt to reference objects which come from a deleted fork --- app/components/moon.hbs | 27 +++++++++++++++++++++++++++ app/components/moon.js | 34 ++++++++++++++++++++++++++++++++++ app/components/planet-list.hbs | 27 +++++++++++++++++++++------ app/components/planet-list.js | 29 +++++++++++++++++++++++++---- app/components/planet.hbs | 3 ++- app/components/planet.js | 4 ++++ app/routes/application.js | 6 ++++-- 7 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 app/components/moon.hbs create mode 100644 app/components/moon.js diff --git a/app/components/moon.hbs b/app/components/moon.hbs new file mode 100644 index 0000000..b745917 --- /dev/null +++ b/app/components/moon.hbs @@ -0,0 +1,27 @@ +
+
+ {{@index}}: + {{#if this.displayEditor}} + + {{else}} + {{@moon.name}} + {{/if}} +
+ +
+ +
+
diff --git a/app/components/moon.js b/app/components/moon.js new file mode 100644 index 0000000..a78f308 --- /dev/null +++ b/app/components/moon.js @@ -0,0 +1,34 @@ +import Component from '@glimmer/component'; +import { inject as service } from '@ember/service'; +import { dropTask } from 'ember-concurrency'; +import { tracked } from '@glimmer/tracking'; + +export default class PlanetComponent extends Component { + @service store; + + @tracked displayEditor = false; + @tracked name = ''; + + @dropTask + *toggleEditor() { + if (this.displayEditor) { + let fork = this.store.fork(); + let moon = fork.cache.findRecord(this.args.moon); + moon.name = this.name; + yield this.store.merge(fork); + fork.destroy(); + } else { + this.name = this.args.moon.name; + } + + this.displayEditor = !this.displayEditor; + } + + @dropTask + *remove(planet) { + let fork = this.store.fork(); + yield fork.removeRecord(planet); + yield this.store.merge(fork); + fork.destroy(); + } +} diff --git a/app/components/planet-list.hbs b/app/components/planet-list.hbs index 1f27ac5..479a378 100644 --- a/app/components/planet-list.hbs +++ b/app/components/planet-list.hbs @@ -1,4 +1,4 @@ -
+
live query
@@ -18,8 +18,8 @@
-
-
static query
+
+
Displayed from fork
+ + +
diff --git a/app/components/planet-list.js b/app/components/planet-list.js index ce7c360..d94d654 100644 --- a/app/components/planet-list.js +++ b/app/components/planet-list.js @@ -18,11 +18,32 @@ export default class PlanetListComponent extends Component { this.displayMoons = !this.displayMoons; } - /* eslint require-yield: off */ + @action + destroyFork() { + this.fork.destroy(); + } + + @action + createFork() { + this.fork = this.store.fork(); + this.requery(); + } + + @action + requery() { + this.staticPlanets = this.fork.cache.findRecords('planet'); + } + @dropTask - *refresh() { - let fork = this.store.fork(); - this.staticPlanets = fork.cache.findRecords('planet'); + *rebase() { + let oldFork = this.fork; + let newFork = this.store.fork(); + yield newFork.merge(oldFork); + this.fork = newFork; + yield oldFork.destroy(); + + // This would fix the issue as it updates references to the new fork + // this.staticPlanets = this.fork.cache.findRecords('planet'); } @dropTask diff --git a/app/components/planet.hbs b/app/components/planet.hbs index d7d51b9..f437f8c 100644 --- a/app/components/planet.hbs +++ b/app/components/planet.hbs @@ -11,6 +11,7 @@ /> {{else}} {{@planet.name}} + -- {{this.moonNames}} {{/if}}
@@ -37,7 +38,7 @@ {{#if @displayMoons}} {{#each @planet.moons as |moon i|}} -
{{i}}: {{moon.name}}
+ {{/each}} {{/if}}
diff --git a/app/components/planet.js b/app/components/planet.js index be8fead..6dc5fc7 100644 --- a/app/components/planet.js +++ b/app/components/planet.js @@ -9,6 +9,10 @@ export default class PlanetComponent extends Component { @tracked displayEditor = false; @tracked name = ''; + get moonNames() { + return this.args.planet.moons.mapBy('name').join(', '); + } + @dropTask *toggleEditor() { if (this.displayEditor) { diff --git a/app/routes/application.js b/app/routes/application.js index ccfb619..d6c71f7 100644 --- a/app/routes/application.js +++ b/app/routes/application.js @@ -5,8 +5,10 @@ export default class ApplicationRoute extends Route { @service dataCoordinator; @service store; - model() { - return this.store.findRecords('planet', { include: ['moons'] }); + async model() { + // return this.store.findRecords('planet', { include: ['moons'] }); + let planet = await this.store.findRecords('planet'); + return this.store.findRecords('moon'); } async beforeModel() {