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

Find records from offline store, then from online store only if not found #33

Open
Leooo opened this issue Apr 11, 2015 · 2 comments
Open

Comments

@Leooo
Copy link

Leooo commented Apr 11, 2015

Small piece of code for this, use

this.emberSync.findOfflineFirst('posts');

or

this.emberSync.findOfflineFirst('post','27');

to get a promise filled with offline store results if any (without fetching the server), otherwise online store results fetched from the server. This can be useful if we want to use localStorage as a cache of user's own data, and reduce the number of requests to the server for records which can only be modified by the user (while still being able to send changes to the server):

import EmberSync from 'ember-sync';
import StoreInitMixin from "ember-sync/store-initialization-mixin";
import Persistence from "ember-sync/persistence";
import Query from 'ember-sync/query';
import Ember from 'ember';

var alreadyRun=false;

export default {
  name: 'override-ember-sync',
  before: 'store',
  initialize: function() {
    if (alreadyRun) {
      return;
    } else {
      alreadyRun=true;
    }

    EmberSync.reopen(StoreInitMixin,{
      findOfflineFirst: function(type, query) {
        var _this = this;
        var syncQuery = Query.create({
          onlineStore:  this.onlineStore,
          offlineStore: this.offlineStore,
          onError:      this.get('onError'),
          onRecordAdded:     function(record) {
            _this.onRecordAdded(record, type);
          }
        });
        return syncQuery.findOfflineFirst(type, query);
      },
    });

    Query.reopen({
      findOfflineFirst: function(type, query) {
        var _this=this;
        var offlineSearch = Ember.isNone(query) ? _this.offlineStore.findAll(type) : _this.offlineStore.find(type, query);
        return new Ember.RSVP.Promise(function(resolve, reject) {
          offlineSearch.then(function(record) {
              if (!record.toArray().length) {
                _this.findOnlineOnly(type, query).then(function(record){resolve(record);},
                                                       function(error){reject(error);});
              }
              else {
                //see https://github.com/kurko/ember-localstorage-adapter/issues/113
                record.forEach(function(rec){
                  if (record.get('id')) {
                    _this.onRecordAdded(record);
                  }
                });
                resolve(record);
              }
          },
          function(error) {
            _this.findOnlineOnly(type, query).then(function(record){resolve(record);},
                                                   function(error){reject(error);});
          });
        });
      },
      findOnlineOnly: function(type, query){
        var _this=this;
        var onlineSearch  = Ember.isNone(query) ? _this.onlineStore.findAll(type) : _this.onlineStore.find(type, query);
        return new Ember.RSVP.Promise(function(resolve, reject) {
          onlineSearch.then(function(record) {
              if (!record.toArray().length) {reject(record);}
              else{
                 record.forEach(function(rec){
                  var id = rec.get('id'),
                      persistenceState = _this.offlineStore.find(type, id);
                  var persistRecordOffline = function(onlineRecord) {
                    var persistence = Persistence.create({
                      onlineStore:  _this.onlineStore,
                      offlineStore: _this.offlineStore,
                    });
                    persistence.persistRecordOffline(type,rec);
                  };
                  persistenceState.then(persistRecordOffline, persistRecordOffline);
                  _this.onRecordAdded(rec);
                });
                resolve(record);
            }
          },function(error){
            reject(error);
          });
        });
      },
    });

  },
}
@kurko
Copy link
Owner

kurko commented Jun 12, 2015

Any chance you could write this as a PR, with some tests? That way we'd be able discuss line by line :D

@kurko
Copy link
Owner

kurko commented Jun 12, 2015

I think something like this.emberSync.findQuery('post', {id: '27', fetchOnline: false}); would be better because then it complies with ED Store interface.

Also, could you move this code into a PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants