Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Section about fetching data #10

Closed
wants to merge 10 commits into from
170 changes: 24 additions & 146 deletions app/routes/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,172 +4,50 @@ export default class ApplicationRoute extends Route {
model() {
return [
{
id: 'generating-files',
id: 'fetching-data',
subsections: [
{
id: 'generating-component',
classicFiles: ['classic.shell'],
octaneFiles: ['octane.shell'],
id: 'find-record',
classicFiles: ['old.js'],
octaneFiles: ['new.js', 'replicate-store.js', 'own-builder.js'],
},
{
id: 'file-structure',
classicFiles: ['classic.text'],
octaneFiles: ['octane.text'],
id: 'find-all',
classicFiles: ['old.js'],
octaneFiles: ['new.js'],
},
],
},
{
id: 'component-templates',
subsections: [
{
id: 'angle-brackets',
classicFiles: ['classic.hbs'],
octaneFiles: ['octane.hbs'],
},
{
id: 'inline-vs-block',
classicFiles: ['classic.hbs'],
octaneFiles: ['octane.hbs'],
},
{
id: 'angle-brackets-nested',
classicFiles: ['classic.hbs'],
octaneFiles: ['octane.hbs'],
},
{
id: 'template-named',
classicFiles: ['classic.hbs'],
octaneFiles: ['octane.hbs'],
},
{
id: 'template-this',
classicFiles: ['classic.hbs'],
octaneFiles: ['octane.hbs'],
},
{
id: 'template-arguments-named',
classicFiles: ['classic.hbs'],
octaneFiles: ['octane.hbs'],
},
{
id: 'template-arguments-this',
classicFiles: ['classic.hbs'],
octaneFiles: ['octane.hbs'],
},
{
id: 'tag-name',
classicFiles: ['classic.hbs', 'classic.html'],
octaneFiles: ['octane.hbs', 'octane.html'],
},
{
id: 'element-id',
classicFiles: ['classic.js', 'classic.hbs'],
octaneFiles: ['octane.js', 'octane.hbs'],
},
],
},
{
id: 'component-properties',
subsections: [
{
id: 'js-boilerplate',
classicFiles: ['classic.js'],
octaneFiles: ['octane.js'],
id: 'query',
classicFiles: ['old.js'],
octaneFiles: ['new.js'],
},
{
id: 'js-properties',
classicFiles: ['classic.js'],
octaneFiles: ['octane.js'],
},
{
id: 'ddau',
classicFiles: [
'classic-parent.js',
'classic-parent.hbs',
'classic-child.js',
'classic-child.hbs',
],
octaneFiles: [
'octane-parent.js',
'octane-parent.hbs',
'octane-child.hbs',
],
},
{
id: 'args',
classicFiles: ['classic.js'],
octaneFiles: ['octane.js'],
},
{
id: 'get-and-set',
classicFiles: ['classic.js'],
octaneFiles: ['octane.js'],
},
{
id: 'tracked-vs-cp',
classicFiles: ['classic.js'],
octaneFiles: ['octane.js'],
},
{
id: 'computed-decorator',
classicFiles: ['classic.js'],
octaneFiles: ['octane.js'],
},
],
},
{
id: 'actions',
subsections: [
{
id: 'actions',
classicFiles: ['classic.js', 'classic.hbs'],
octaneFiles: ['octane.js', 'octane.hbs'],
},
{
id: 'template-arguments-default',
classicFiles: ['classic.hbs', 'classic.js'],
octaneFiles: ['octane.hbs', 'octane.js'],
},
{
id: 'mixins',
classicFiles: ['classic.js'],
octaneDescriptionKey: 'actions.mixins.octaneDescription',
id: 'query-record',
classicFiles: ['old.js'],
octaneFiles: ['new.js'],
},
],
},
{
id: 'component-lifecycle',
id: 'adapters',
subsections: [
{
id: 'constructors',
classicFiles: ['classic.js'],
octaneFiles: ['octane.js'],
id: 'general',
},
{
id: 'will-destroy',
classicFiles: ['classic.js'],
octaneFiles: ['octane.js'],
id: 'host-and-namespace',
classicFiles: ['old.js'],
octaneFiles: ['new.js'],
},
{
id: 'render-modifiers',
classicDescriptionKey:
'component-lifecycle.render-modifiers.classicDescription',
octaneFiles: ['octane.shell'],
id: 'path-for-type',
classicFiles: ['old.js'],
octaneFiles: ['new.js', 'utils.js'],
},
{
id: 'did-insert',
classicFiles: ['classic.hbs', 'classic.js'],
octaneFiles: ['octane.hbs', 'octane.js'],
},
],
},
{
id: 'routes',
subsections: [
{
id: 'model-access',
classicFiles: ['classic.hbs'],
octaneFiles: ['octane.hbs'],
id: 'cache-lifetime',
classicFiles: ['old.js'],
octaneFiles: ['new.js'],
},
],
},
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions snippets/adapters/cache-lifetime/new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { LifetimesService } from '@ember-data/request-utils';
import DataStore from '@ember-data/store';

export default class Store extends DataStore {
constructor(args) {
super(args);
// This is default configuration that would be set automatically be Ember Data
// this.lifetimes = new LifetimesService(this, {
// apiCacheSoftExpires: 30_000,
// apiCacheHardExpires: 60_000
// });
this.lifetimes = {
isHardExpired(identifier) {
const cached = this.store.cache.peekRequest(identifier);
const twentyMinutesInMs = 20 * 60 * 1000;

function isStale(headers, expirationTime) {
const date = headers.get('date');

if (!date) {
return true;
}

const time = new Date(date).getTime();
const now = Date.now();
const deadline = time + expirationTime;

const result = now > deadline;

return result;
}

return !cached || !cached.response || isStale(cached.response.headers, twentyMinutesInMs);
},

isSoftExpired(identifier) {
const { downlink, effectiveType } = navigator.connection;

return downlink > 0 && effectiveType === '4g';
}
}
}
}
41 changes: 41 additions & 0 deletions snippets/adapters/cache-lifetime/old.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import JSONAPIAdapter from '@ember-data/adapter/json-api';

export default class ApplicationAdapter extends JSONAPIAdapter {
shouldBackgroundReloadAll(store, snapshotArray) {
let { downlink, effectiveType } = navigator.connection;

return downlink > 0 && effectiveType === '4g';
}

shouldBackgroundReloadRecord(store, snapshot) {
let { downlink, effectiveType } = navigator.connection;

return downlink > 0 && effectiveType === '4g';
}

shouldReloadRecord(store, ticketSnapshot) {
let lastAccessedAt = ticketSnapshot.attr('lastAccessedAt');
let timeDiff = moment().diff(lastAccessedAt, 'minutes');

if (timeDiff > 20) {
return true;
} else {
return false;
}
}

shouldReloadAll(store, snapshotArray) {
let snapshots = snapshotArray.snapshots();

return snapshots.any((ticketSnapshot) => {
let lastAccessedAt = ticketSnapshot.attr('lastAccessedAt');
let timeDiff = moment().diff(lastAccessedAt, 'minutes');

if (timeDiff > 20) {
return true;
} else {
return false;
}
});
}
}
7 changes: 7 additions & 0 deletions snippets/adapters/host-and-namespace/new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { setBuildURLConfig } from '@ember-data/request-utils';
import config from 'my-app/config/environment';

setBuildURLConfig({
host: config.api.host,
namespace: config.api.namespace,
});
7 changes: 7 additions & 0 deletions snippets/adapters/host-and-namespace/old.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import JSONAPIAdapter from '@ember-data/adapter/json-api';
import config from 'my-app/config/environment';

export default class ApplicationAdapter extends JSONAPIAdapter {
host = config.api.host;
namespace = config.api.namespace;
}
12 changes: 12 additions & 0 deletions snippets/adapters/path-for-type/new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { findRecord } from '@ember-data/json-api/request';
// import { findRecord } from '@ember-data/rest/request';
// import { findRecord } from '@ember-data/active-record/request';

const dynamicPathFor = (identifierType) => {
const collectionName = camelize(pluralize(identifierType))
return `collections/${collectionName}/records`;
};

const options = findRecord('post', '1', {
resourcePath: dynamicPathFor('post'),
})
6 changes: 6 additions & 0 deletions snippets/adapters/path-for-type/old.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default class ApplicationAdapter extends JSONAPIAdapter {
pathForType(type) {
const collectionName = pluralize(camelize(type));
return `collections/${collectionName}/records`;
}
}
60 changes: 60 additions & 0 deletions snippets/adapters/path-for-type/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { camelize } from '@ember/string';
import { pluralize } from 'ember-inflector';
import { recordIdentifierFor } from '@ember-data/store';

import {
findRecord as restFindRecord,
query as restQuery,
createRecord as restCreateRecord,
updateRecord as restUpdateRecord,
deleteRecord as restDeleteRecord,
} from '@ember-data/rest/request';

const _customResourcePath = (identifierType) => {
return `collections/${camelize(pluralize(identifierType))}/records`;
};

const findRecord = (identifierType, id, options) => {
options = {
...options,
resourcePath: _customResourcePath(identifierType),
};
return restFindRecord(identifierType, id, options);
};

const query = (identifierType, query, options) => {
options = {
...options,
resourcePath: _customResourcePath(identifierType),
};
return restQuery(identifierType, query, options);
};

const createRecord = (record, options) => {
const identifier = recordIdentifierFor(record);
options = {
...options,
resourcePath: _customResourcePath(identifier.type),
};
return restCreateRecord(record, options);
};

const updateRecord = (record, options) => {
const identifier = recordIdentifierFor(record);
options = {
...options,
resourcePath: _customResourcePath(identifier.type),
};
return restUpdateRecord(record, options);
};

const deleteRecord = (record, options) => {
const identifier = recordIdentifierFor(record);
options = {
...options,
resourcePath: _customResourcePath(identifier.type),
};
return restDeleteRecord(record, options);
};

export { findRecord, query, createRecord, updateRecord, deleteRecord };
4 changes: 4 additions & 0 deletions snippets/fetching-data/find-all/new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { query } from '@ember-data/json-api/request';

await this.store.request(query('user'));
const users = this.store.peekAll('user')
Loading
Loading