I have a question about loading and caching remote objects with Ember. I\'m developing an Ember app that uses server-side storage through a REST API. Some of the fetched data is
Here's a way to do it. A mixin for your adapters, with a method localStoreRecord
you can use to cache the record, lastly an initializer to preload the store.
Local Storage is simply a key:value store for stringified objects, so we can store all of our application data under a single key.
Note: this is using es6 modules
// app/mixins/local-storage.js
import Ember from 'ember';
export default Ember.Mixin.create({
appName: 'myApp',
// how many records per model to store locally, can be improved.
// needed to prevent going over localStorage's 5mb limit
localStorageLimit: 5,
localStoreRecord: function(record) {
var data = JSON.parse(localStorage.getItem(this.appName));
data = data || {};
data[this.modelName] = data[this.modelName] || [];
var isNew = data[this.modelName].every(function(rec) {
rec.id !== record.id;
});
if (isNew) {
data[this.modelName].push(record);
if (data[this.modelName].length > this.localStorageLimit) {
data[this.modelName].shift();
}
localStorage.setItem(this.appName, JSON.stringify(data));
}
}
});
// app/adapters/skateboard.js
import DS from 'ember-data';
import Ember from 'ember';
import LocalStorageMixin from '../mixins/local-storage';
export default DS.RESTAdapter.extend(LocalStorageMixin, {
modelName: 'skateboard',
find: function(store, type, id) {
var self = this;
var url = [type,id].join('/');
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
url: 'api/' + url,
type: 'GET'
}).done(function (response) {
// cache the response in localStorage
self.localStoreRecord(response);
resolve({ type: response });
}).fail(function(jqHXR, responseStatus) {
reject(new Error(type +
' request failed with status=' + reponseStatus);
});
});
},
updateRecord: function(store, type, record) {
var data = this.serialize(record, { includeId: true });
var id = record.get('id');
var url = [type, id].join('/');
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
type: 'PUT',
url: 'api/' + url,
dataType: 'json',
data: data
}).then(function(data) {
// cache the response in localStorage
self.localStoreRecord(response);
resolve({ type: response });
}).fail(function(jqXHR, responseData) {
reject(new Error(type +
' request failed with status=' + reponseStatus);
});
});
}
});
// app/initializers/local-storage.js
export var initialize = function(container/*, application*/) {
var appName = 'myApp';
var store = container.lookup('store:main');
var data = JSON.parse(localStorage.getItem(appName));
console.log('localStorage:',data);
if (!data) {
return;
}
var keys = Object.keys(data);
if (keys.length) {
keys.forEach(function(key) {
console.log(key,data[key][0]);
store.createRecord(key, data[key][0]);
});
}
};
export default {
name: 'local-storage',
after: 'store',
initialize: initialize
};