Skip to content

Instantly share code, notes, and snippets.

@DingoEatingFuzz
Last active April 25, 2020 20:56
Show Gist options
  • Save DingoEatingFuzz/cd933941716b7f8402842ee098d0a99c to your computer and use it in GitHub Desktop.
Save DingoEatingFuzz/cd933941716b7f8402842ee098d0a99c to your computer and use it in GitHub Desktop.
alias-404-double-load
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
export default Controller.extend({
appName: 'Ember Twiddle',
filterOne: computed('model.[]', 'model.@each.parent', function() {
return this.model.compact().filter(m => {
m.get('parent');
return true;
});
}),
filterTwo: computed('filterOne.[]', function() {
return this.filterOne.filter(() => true);
}),
aliasOne: alias('filterTwo'),
broken: computed('aliasOne.[]', function() {
return this.aliasOne;
}),
});
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';
export default Model.extend({
name: attr('string'),
parent: belongsTo('thing'),
})
import Route from '@ember/routing/route';
import Pretender from 'pretender';
const things = {
data: [{
type: 'thing',
id: 1,
attributes: {
name: 'Child'
},
relationships: {
parent: {
data: {
type: 'thing',
id: 404
}
}
}
}]
};
export default Route.extend({
beforeModel() {
this.server = new Pretender(function() {
this.get('/things', () => [200, {}, JSON.stringify(things)]);
this.get('/things/:id', (req) => {
console.info(`Requesting a single job: ${req.params.id}`);
return [404, {}, 'Not found'];
});
});
this.server.handledRequest = function(method, url, request) {
console.groupCollapsed(`${method}: ${url}`);
console.log(JSON.stringify(JSON.parse(request.responseText), null, 2));
console.groupEnd();
}
},
model() {
return this.store.findAll('thing', { reload: true });
}
});
<h1>404 race condition thing because of alias, I guess</h1>
<p>Some peculiar interaction I have narrowed down to <code>alias</code> is causing the <code>belongsTo</code> for the single model to be fetched twice.</p>
<p>The first fetch errors with a 404 which is to be expected, but the second request throws a "Cannot read property 'isDestroying' of null" error due to the internalModel for the 404'd parent model no longer having a record.</p>
<p>I suspect this is due to a race condition in which the second request occurs before the internal model has settled from the first request. The currentState of the internal model suggests this too.</p>
<strong>Delete the broken line below to see that it is what causes the double 404.</strong>
<ol>
<li>Model: {{model.length}}</li>
<li>Filter One: {{filterOne.length}}</li>
<li>Filter Two: {{filterTwo.length}}</li>
<li>Alias One: {{aliasOne.length}}</li>
<li>Broken: {{broken.length}}</li>
</ol>
{
"version": "0.17.0",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.12.2",
"ember-template-compiler": "3.12.2",
"ember-testing": "3.12.2",
"route-recognizer": "https://rawgit.com/tildeio/route-recognizer/56f5fcec6ae58d8e86b5dc77609809fb91198142/dist/route-recognizer.js",
"FakeXMLHttpRequest": "https://rawgit.com/pretenderjs/FakeXMLHttpRequest/23c3a96b5b24f1bfe595867437e4f128a29c2840/fake_xml_http_request.js",
"pretender": "https://rawgit.com/pretenderjs/pretender/c6de9afe18b1472aded2592f5a80ad9a26a0e262/pretender.js"
},
"addons": {
"@glimmer/component": "1.0.0",
"ember-data": "3.16.2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment